devices/e1000/e1000_main-2.6.27-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 13:12:24 -0400
changeset 2629 a2701af27fde
parent 2255 25b351a76050
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.
1900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k3-NAPI"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static struct pci_device_id e1000_pci_tbl[] = {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static int e1000_set_mac(struct net_device *netdev, void *p);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static irqreturn_t e1000_intr(int irq, void *data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr_msi(int irq, void *data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
				  struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
				  int *work_done, int work_to_do);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
                                   struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				   int cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
                                      struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
				      int cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			   int cmd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_tx_timeout(struct net_device *dev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_reset_task(struct work_struct *work);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_smartspeed(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
                                       struct sk_buff *skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_restore_vlan(struct e1000_adapter *adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
#ifdef CONFIG_PM
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static int e1000_resume(struct pci_dev *pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_shutdown(struct pci_dev *pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
#ifdef CONFIG_NET_POLL_CONTROLLER
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
/* for netdump / net console */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_netpoll (struct net_device *netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#define COPYBREAK_DEFAULT 256
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
module_param(copybreak, uint, 0644);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
MODULE_PARM_DESC(copybreak,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	"Maximum size of packet that is copied to a new buffer on receive");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
                     pci_channel_state_t state);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_io_resume(struct pci_dev *pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static struct pci_error_handlers e1000_err_handler = {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	.error_detected = e1000_io_error_detected,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	.slot_reset = e1000_io_slot_reset,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.resume = e1000_io_resume,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
};
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static struct pci_driver e1000_driver = {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.name     = e1000_driver_name,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	.id_table = e1000_pci_tbl,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.probe    = e1000_probe,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.remove   = __devexit_p(e1000_remove),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#ifdef CONFIG_PM
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	/* Power Managment Hooks */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.suspend  = e1000_suspend,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.resume   = e1000_resume,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.shutdown = e1000_shutdown,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.err_handler = &e1000_err_handler
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
};
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
MODULE_LICENSE("GPL");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
MODULE_VERSION(DRV_VERSION);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
module_param(debug, int, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 * e1000_init_module - Driver Registration Routine
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 * e1000_init_module is the first routine called when the driver is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 * loaded. All it does is register with the PCI subsystem.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
static int __init e1000_init_module(void)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	int ret;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	printk(KERN_INFO "%s - version %s\n",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	       e1000_driver_string, e1000_driver_version);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	printk(KERN_INFO "%s\n", e1000_copyright);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	ret = pci_register_driver(&e1000_driver);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	if (copybreak != COPYBREAK_DEFAULT) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
		if (copybreak == 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
			printk(KERN_INFO "e1000: copybreak disabled\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
		else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
			printk(KERN_INFO "e1000: copybreak enabled for "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
			       "packets <= %u bytes\n", copybreak);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	return ret;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
module_init(e1000_init_module);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 * e1000_exit_module - Driver Exit Cleanup Routine
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
 * e1000_exit_module is called just before the driver is removed
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
 * from memory.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
static void __exit e1000_exit_module(void)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	pci_unregister_driver(&e1000_driver);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
module_exit(e1000_exit_module);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
static int e1000_request_irq(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	irq_handler_t handler = e1000_intr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	int irq_flags = IRQF_SHARED;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	int err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	if (hw->mac_type >= e1000_82571) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		adapter->have_msi = !pci_enable_msi(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		if (adapter->have_msi) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
			handler = e1000_intr_msi;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
			irq_flags = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	                  netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		if (adapter->have_msi)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
			pci_disable_msi(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		        "Unable to allocate interrupt Error: %d\n", err);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
static void e1000_free_irq(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	free_irq(adapter->pdev->irq, netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	if (adapter->have_msi)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		pci_disable_msi(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
 * e1000_irq_disable - Mask off interrupt generation on the NIC
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
static void e1000_irq_disable(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	ew32(IMC, ~0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	synchronize_irq(adapter->pdev->irq);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
 * e1000_irq_enable - Enable default interrupt generation settings
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
static void e1000_irq_enable(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	ew32(IMS, IMS_ENABLE_MASK);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	u16 vid = hw->mng_cookie.vlan_id;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	u16 old_vid = adapter->mng_vlan_id;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	if (adapter->vlgrp) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
			if (hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
				e1000_vlan_rx_add_vid(netdev, vid);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
				adapter->mng_vlan_id = vid;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
			} else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
					(vid != old_vid) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
				e1000_vlan_rx_kill_vid(netdev, old_vid);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		} else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
			adapter->mng_vlan_id = vid;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
 * e1000_release_hw_control - release control of the h/w to f/w
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
 * For ASF and Pass Through versions of f/w this means that the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
 * driver is no longer loaded. For AMT version (only with 82573) i
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
 * of the f/w this means that the network i/f is closed.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
static void e1000_release_hw_control(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	u32 ctrl_ext;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
	u32 swsm;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	/* Let firmware taken over control of h/w */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		swsm = er32(SWSM);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
		ctrl_ext = er32(CTRL_EXT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
 * e1000_get_hw_control - get control of the h/w from f/w
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
 * For ASF and Pass Through versions of f/w this means that
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
 * the driver is loaded. For AMT version (only with 82573)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
 * of the f/w this means that the network i/f is open.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
static void e1000_get_hw_control(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	u32 ctrl_ext;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	u32 swsm;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	/* Let firmware know the driver has taken over */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		swsm = er32(SWSM);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		ctrl_ext = er32(CTRL_EXT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
static void e1000_init_manageability(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	if (adapter->en_mng_pt) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		u32 manc = er32(MANC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		/* disable hardware interception of ARP */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
		manc &= ~(E1000_MANC_ARP_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		/* enable receiving management packets to the host */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		/* this will probably generate destination unreachable messages
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		 * from the host OS, but the packets will be handled on SMBUS */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
		if (hw->has_manc2h) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
			u32 manc2h = er32(MANC2H);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
			manc |= E1000_MANC_EN_MNG2HOST;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
#define E1000_MNG2HOST_PORT_623 (1 << 5)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
#define E1000_MNG2HOST_PORT_664 (1 << 6)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
			manc2h |= E1000_MNG2HOST_PORT_623;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
			manc2h |= E1000_MNG2HOST_PORT_664;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
			ew32(MANC2H, manc2h);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
		ew32(MANC, manc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
static void e1000_release_manageability(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	if (adapter->en_mng_pt) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		u32 manc = er32(MANC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		/* re-enable hardware interception of ARP */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		manc |= E1000_MANC_ARP_EN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		if (hw->has_manc2h)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
			manc &= ~E1000_MANC_EN_MNG2HOST;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		/* don't explicitly have to mess with MANC2H since
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		 * MANC has an enable disable that gates MANC2H */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		ew32(MANC, manc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
 * e1000_configure - configure the hardware for RX and TX
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
 * @adapter = private board structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
static void e1000_configure(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	e1000_set_rx_mode(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	e1000_restore_vlan(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	e1000_init_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	e1000_configure_tx(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	e1000_setup_rctl(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	e1000_configure_rx(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	/* call E1000_DESC_UNUSED which always leaves
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	 * at least 1 descriptor unused to make sure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	 * next_to_use != next_to_clean */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	for (i = 0; i < adapter->num_rx_queues; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		adapter->alloc_rx_buf(adapter, ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		                      E1000_DESC_UNUSED(ring));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	adapter->tx_queue_len = netdev->tx_queue_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
int e1000_up(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	/* hardware has been reset, we need to reload some things */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	e1000_configure(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	clear_bit(__E1000_DOWN, &adapter->flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	napi_enable(&adapter->napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	/* fire a link change interrupt to start the watchdog */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	ew32(ICS, E1000_ICS_LSC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
 * e1000_power_up_phy - restore link in case the phy was powered down
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
 * The phy may be powered down to save power and turn off link when the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
 * driver is unloaded and wake on lan is not enabled (among others)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
 * *** this routine MUST be followed by a call to e1000_reset ***
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
void e1000_power_up_phy(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	u16 mii_reg = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	/* Just clear the power down bit to wake the phy back up */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	if (hw->media_type == e1000_media_type_copper) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		/* according to the manual, the phy will retain its
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		 * settings across a power-down/up cycle */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		mii_reg &= ~MII_CR_POWER_DOWN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
static void e1000_power_down_phy(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	/* Power down the PHY so no link is implied when interface is down *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	 * The PHY cannot be powered down if any of the following is true *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	 * (a) WoL is enabled
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	 * (b) AMT is active
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	 * (c) SoL/IDER session is active */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	   hw->media_type == e1000_media_type_copper) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		u16 mii_reg = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		case e1000_82540:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		case e1000_82545:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		case e1000_82545_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
		case e1000_82546:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		case e1000_82546_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		case e1000_82541:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		case e1000_82541_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		case e1000_82547:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		case e1000_82547_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
				goto out;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
			if (e1000_check_mng_mode(hw) ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
			    e1000_check_phy_reset_block(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
				goto out;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
			goto out;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		mii_reg |= MII_CR_POWER_DOWN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		mdelay(1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
out:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
void e1000_down(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	/* signal that we're down so the interrupt handler does not
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	 * reschedule our watchdog timer */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	set_bit(__E1000_DOWN, &adapter->flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	napi_disable(&adapter->napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	e1000_irq_disable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	del_timer_sync(&adapter->tx_fifo_stall_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	del_timer_sync(&adapter->watchdog_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	del_timer_sync(&adapter->phy_info_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	netdev->tx_queue_len = adapter->tx_queue_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	adapter->link_speed = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	adapter->link_duplex = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	netif_carrier_off(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	e1000_clean_all_tx_rings(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	e1000_clean_all_rx_rings(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
void e1000_reinit_locked(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	WARN_ON(in_interrupt());
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		msleep(1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	e1000_down(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	e1000_up(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	clear_bit(__E1000_RESETTING, &adapter->flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
void e1000_reset(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	bool legacy_pba_adjust = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	/* Repartition Pba for greater than 9k mtu
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	 * To take effect CTRL.RST is required.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	case e1000_82542_rev2_0:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	case e1000_82542_rev2_1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	case e1000_82543:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	case e1000_82544:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	case e1000_82540:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	case e1000_82541:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	case e1000_82541_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		legacy_pba_adjust = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		pba = E1000_PBA_48K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	case e1000_82545:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	case e1000_82545_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	case e1000_82546:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	case e1000_82546_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		pba = E1000_PBA_48K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	case e1000_82547:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	case e1000_82547_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		legacy_pba_adjust = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		pba = E1000_PBA_30K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		pba = E1000_PBA_38K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		pba = E1000_PBA_20K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		pba = E1000_PBA_8K;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	case e1000_undefined:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	case e1000_num_macs:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	if (legacy_pba_adjust) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
			pba -= 8; /* allocate more FIFO for Tx */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		if (hw->mac_type == e1000_82547) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
			adapter->tx_fifo_head = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
			adapter->tx_fifo_size =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
			atomic_set(&adapter->tx_fifo_stall, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	} else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		/* adjust PBA for jumbo frames */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		ew32(PBA, pba);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		/* To maintain wire speed transmits, the Tx FIFO should be
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		 * large enough to accomodate two full transmit packets,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		 * the Rx FIFO should be large enough to accomodate at least
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		 * one full receive packet and is similarly rounded up and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		 * expressed in KB. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		pba = er32(PBA);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		/* upper 16 bits has Tx packet buffer allocation size in KB */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		tx_space = pba >> 16;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		/* lower 16 bits has Rx packet buffer allocation size in KB */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		pba &= 0xffff;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		/* don't include ethernet FCS because hardware appends/strips */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		               VLAN_TAG_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		min_tx_space = min_rx_space;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		min_tx_space *= 2;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		min_tx_space = ALIGN(min_tx_space, 1024);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		min_tx_space >>= 10;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		min_rx_space = ALIGN(min_rx_space, 1024);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		min_rx_space >>= 10;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		/* If current Tx allocation is less than the min Tx FIFO size,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
		 * and the min Tx FIFO size is less than the current Rx FIFO
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
		 * allocation, take space away from current Rx allocation */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		if (tx_space < min_tx_space &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
		    ((min_tx_space - tx_space) < pba)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
			pba = pba - (min_tx_space - tx_space);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
			/* PCI/PCIx hardware has PBA alignment constraints */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
			switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
			case e1000_82545 ... e1000_82546_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
				pba &= ~(E1000_PBA_8K - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
			default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
			/* if short on rx space, rx wins and must trump tx
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
			 * adjustment or use Early Receive if available */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
			if (pba < min_rx_space) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
				switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
				case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
					/* ERT enabled in e1000_configure_rx */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
				default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
					pba = min_rx_space;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	ew32(PBA, pba);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	/* flow control settings */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	/* Set the FC high water mark to 90% of the FIFO size.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	 * Required to clear last 3 LSB */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	/* We can't use 90% on small FIFOs because the remainder
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	 * would be less than 1 full frame.  In this case, we size
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	 * it to allow at least a full frame above the high water
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	 *  mark. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	if (pba < E1000_PBA_16K)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		fc_high_water_mark = (pba * 1024) - 1600;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	hw->fc_high_water = fc_high_water_mark;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	hw->fc_low_water = fc_high_water_mark - 8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	if (hw->mac_type == e1000_80003es2lan)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		hw->fc_pause_time = 0xFFFF;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		hw->fc_pause_time = E1000_FC_PAUSE_TIME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	hw->fc_send_xon = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	hw->fc = hw->original_fc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	/* Allow time for pending master requests to run */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	e1000_reset_hw(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	if (hw->mac_type >= e1000_82544)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
		ew32(WUC, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	if (e1000_init_hw(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		DPRINTK(PROBE, ERR, "Hardware Error\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	e1000_update_mng_vlan(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	if (hw->mac_type >= e1000_82544 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	    hw->mac_type <= e1000_82547_rev_2 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	    hw->autoneg == 1 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		u32 ctrl = er32(CTRL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		/* clear phy power management bit if we are in gig only mode,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		 * which if enabled will attempt negotiation to 100Mb, which
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
		 * can cause a loss of link at power off or driver unload */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		ctrl &= ~E1000_CTRL_SWDPIN3;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		ew32(CTRL, ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	e1000_reset_adaptive(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	e1000_phy_get_info(hw, &adapter->phy_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	if (!adapter->smart_power_down &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	    (hw->mac_type == e1000_82571 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	     hw->mac_type == e1000_82572)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		u16 phy_data = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		/* speed up time to link by disabling smart power down, ignore
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		 * the return value of this function because there is nothing
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		 * different we would do if it failed */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		                   &phy_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		phy_data &= ~IGP02E1000_PM_SPD;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		                    phy_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	e1000_release_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 *  Dump the eeprom for users having checksum issues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	struct ethtool_eeprom eeprom;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	const struct ethtool_ops *ops = netdev->ethtool_ops;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	u8 *data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	u16 csum_old, csum_new = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	eeprom.len = ops->get_eeprom_len(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	eeprom.offset = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	data = kmalloc(eeprom.len, GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	if (!data) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		       " data\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	ops->get_eeprom(netdev, &eeprom, data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		csum_new += data[i] + (data[i + 1] << 8);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	csum_new = EEPROM_SUM - csum_new;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	printk(KERN_ERR "/*********************/\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	printk(KERN_ERR "Offset    Values\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	printk(KERN_ERR "========  ======\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	printk(KERN_ERR "Include this output when contacting your support "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	       "provider.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	printk(KERN_ERR "This is not a software error! Something bad "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	       "happened to your hardware or\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	printk(KERN_ERR "EEPROM image. Ignoring this "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	       "problem could result in further problems,\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	       "which is invalid\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	printk(KERN_ERR "and requires you to set the proper MAC "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	       "address manually before continuing\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	printk(KERN_ERR "to enable this network device.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	       "to your hardware vendor\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	printk(KERN_ERR "or Intel Customer Support.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	printk(KERN_ERR "/*********************/\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	kfree(data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
 * @pdev: PCI device information struct
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
 * Return true if an adapter needs ioport resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
static int e1000_is_need_ioport(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	switch (pdev->device) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	case E1000_DEV_ID_82540EM:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	case E1000_DEV_ID_82540EM_LOM:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	case E1000_DEV_ID_82540EP:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	case E1000_DEV_ID_82540EP_LOM:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	case E1000_DEV_ID_82540EP_LP:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	case E1000_DEV_ID_82541EI:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	case E1000_DEV_ID_82541EI_MOBILE:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	case E1000_DEV_ID_82541ER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	case E1000_DEV_ID_82541ER_LOM:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	case E1000_DEV_ID_82541GI:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	case E1000_DEV_ID_82541GI_LF:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	case E1000_DEV_ID_82541GI_MOBILE:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	case E1000_DEV_ID_82544EI_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	case E1000_DEV_ID_82544EI_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	case E1000_DEV_ID_82544GC_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	case E1000_DEV_ID_82544GC_LOM:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	case E1000_DEV_ID_82545EM_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	case E1000_DEV_ID_82545EM_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	case E1000_DEV_ID_82546EB_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	case E1000_DEV_ID_82546EB_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
		return true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		return false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
 * e1000_probe - Device Initialization Routine
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
 * @pdev: PCI device information struct
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
 * @ent: entry in e1000_pci_tbl
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
 * Returns 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
 * e1000_probe initializes an adapter identified by a pci_dev structure.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
 * The OS initialization, configuring of the adapter private structure,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
 * and a hardware reset occur.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
static int __devinit e1000_probe(struct pci_dev *pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
				 const struct pci_device_id *ent)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	struct net_device *netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	struct e1000_adapter *adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	struct e1000_hw *hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	static int cards_found = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	int i, err, pci_using_dac;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	u16 eeprom_data = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	int bars, need_ioport;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	DECLARE_MAC_BUF(mac);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	/* do not allocate ioport bars when not needed */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	need_ioport = e1000_is_need_ioport(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	if (need_ioport) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		err = pci_enable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		err = pci_enable_device_mem(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		pci_using_dac = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
			if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
				E1000_ERR("No usable DMA configuration, "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
					  "aborting\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
				goto err_dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		pci_using_dac = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		goto err_pci_reg;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	pci_set_master(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	err = -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	if (!netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		goto err_alloc_etherdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	SET_NETDEV_DEV(netdev, &pdev->dev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	pci_set_drvdata(pdev, netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	adapter->netdev = netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	adapter->pdev = pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	adapter->msg_enable = (1 << debug) - 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	adapter->bars = bars;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	adapter->need_ioport = need_ioport;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	hw->back = adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	err = -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	hw->hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
			      pci_resource_len(pdev, BAR_0));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	if (!hw->hw_addr)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		goto err_ioremap;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	if (adapter->need_ioport) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
		for (i = BAR_1; i <= BAR_5; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
			if (pci_resource_len(pdev, i) == 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
				continue;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
				hw->io_base = pci_resource_start(pdev, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	netdev->open = &e1000_open;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	netdev->stop = &e1000_close;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	netdev->hard_start_xmit = &e1000_xmit_frame;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	netdev->get_stats = &e1000_get_stats;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	netdev->set_rx_mode = &e1000_set_rx_mode;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	netdev->set_mac_address = &e1000_set_mac;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	netdev->change_mtu = &e1000_change_mtu;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	netdev->do_ioctl = &e1000_ioctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	e1000_set_ethtool_ops(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	netdev->tx_timeout = &e1000_tx_timeout;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	netdev->watchdog_timeo = 5 * HZ;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	netdev->vlan_rx_register = e1000_vlan_rx_register;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
#ifdef CONFIG_NET_POLL_CONTROLLER
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	netdev->poll_controller = e1000_netpoll;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	adapter->bd_number = cards_found;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	/* setup the private structure */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	err = e1000_sw_init(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		goto err_sw_init;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	err = -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	/* Flash BAR mapping must happen after e1000_sw_init
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	 * because it depends on mac_type */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	if ((hw->mac_type == e1000_ich8lan) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		hw->flash_address =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			ioremap(pci_resource_start(pdev, 1),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
				pci_resource_len(pdev, 1));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		if (!hw->flash_address)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
			goto err_flashmap;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	if (e1000_check_phy_reset_block(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	if (hw->mac_type >= e1000_82543) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		netdev->features = NETIF_F_SG |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
				   NETIF_F_HW_CSUM |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
				   NETIF_F_HW_VLAN_TX |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
				   NETIF_F_HW_VLAN_RX |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
				   NETIF_F_HW_VLAN_FILTER;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		if (hw->mac_type == e1000_ich8lan)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	if ((hw->mac_type >= e1000_82544) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	   (hw->mac_type != e1000_82547))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		netdev->features |= NETIF_F_TSO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	if (hw->mac_type > e1000_82547_rev_2)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		netdev->features |= NETIF_F_TSO6;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	if (pci_using_dac)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		netdev->features |= NETIF_F_HIGHDMA;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	netdev->features |= NETIF_F_LLTX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	/* initialize eeprom parameters */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	if (e1000_init_eeprom_params(hw)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		E1000_ERR("EEPROM initialization failed\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		goto err_eeprom;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	/* before reading the EEPROM, reset the controller to
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	 * put the device in a known good starting state */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	e1000_reset_hw(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	/* make sure the EEPROM is good */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	if (e1000_validate_eeprom_checksum(hw) < 0) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		e1000_dump_eeprom(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		/*
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		 * set MAC address to all zeroes to invalidate and temporary
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		 * disable this device for the user. This blocks regular
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		 * traffic while still permitting ethtool ioctls from reaching
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		 * the hardware as well as allowing the user to run the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		 * interface after manually setting a hw addr using
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		 * `ip set address`
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		memset(hw->mac_addr, 0, netdev->addr_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		/* copy the MAC address out of the EEPROM */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		if (e1000_read_mac_addr(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	/* don't block initalization here due to bad MAC address */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	if (!is_valid_ether_addr(netdev->perm_addr))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	e1000_get_bus_info(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	init_timer(&adapter->tx_fifo_stall_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	init_timer(&adapter->watchdog_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	adapter->watchdog_timer.function = &e1000_watchdog;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	adapter->watchdog_timer.data = (unsigned long) adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	init_timer(&adapter->phy_info_timer);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	adapter->phy_info_timer.function = &e1000_update_phy_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	adapter->phy_info_timer.data = (unsigned long)adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	e1000_check_options(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	/* Initial Wake on LAN setting
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	 * If APM wake is enabled in the EEPROM,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	 * enable the ACPI Magic Packet filter
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	case e1000_82542_rev2_0:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	case e1000_82542_rev2_1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	case e1000_82543:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	case e1000_82544:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		e1000_read_eeprom(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		e1000_read_eeprom(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	case e1000_82546:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	case e1000_82546_rev_3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
			e1000_read_eeprom(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		/* Fall Through */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		e1000_read_eeprom(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	if (eeprom_data & eeprom_apme_mask)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		adapter->eeprom_wol |= E1000_WUFC_MAG;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	/* now that we have the eeprom settings, apply the special cases
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	 * where the eeprom may be wrong or the board simply won't support
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	 * wake on lan on a particular port */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	switch (pdev->device) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	case E1000_DEV_ID_82546GB_PCIE:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		adapter->eeprom_wol = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	case E1000_DEV_ID_82546EB_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	case E1000_DEV_ID_82546GB_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	case E1000_DEV_ID_82571EB_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		/* Wake events only supported on port A for dual fiber
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		 * regardless of eeprom setting */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
			adapter->eeprom_wol = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	case E1000_DEV_ID_82571EB_QUAD_FIBER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	case E1000_DEV_ID_82571PT_QUAD_COPPER:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		/* if quad port adapter, disable WoL on all but port A */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		if (global_quad_port_a != 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			adapter->eeprom_wol = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
			adapter->quad_port_a = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		/* Reset for multiple quad port adapters */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		if (++global_quad_port_a == 4)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
			global_quad_port_a = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	/* initialize the wol settings based on the eeprom settings */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	adapter->wol = adapter->eeprom_wol;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	/* print bus type/speed/width info */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		 "32-bit"));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	printk("%s\n", print_mac(mac, netdev->dev_addr));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	if (hw->bus_type == e1000_bus_type_pci_express) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
			"longer be supported by this driver in the future.\n",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
			pdev->vendor, pdev->device);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
			"driver instead.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	/* reset the hardware with the new settings */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	/* If the controller is 82573 and f/w is AMT, do not set
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	 * DRV_LOAD until the interface is up.  For all other cases,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	 * let the f/w know that the h/w is now under the control
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	 * of the driver. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	if (hw->mac_type != e1000_82573 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	    !e1000_check_mng_mode(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		e1000_get_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	/* tell the stack to leave us alone until e1000_open() is called */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	netif_carrier_off(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	strcpy(netdev->name, "eth%d");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	err = register_netdev(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		goto err_register;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	cards_found++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
err_register:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
err_eeprom:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	if (!e1000_check_phy_reset_block(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		e1000_phy_hw_reset(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	if (hw->flash_address)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		iounmap(hw->flash_address);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
err_flashmap:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	for (i = 0; i < adapter->num_rx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		dev_put(&adapter->polling_netdev[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	kfree(adapter->tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	kfree(adapter->rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	kfree(adapter->polling_netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
err_sw_init:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	iounmap(hw->hw_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
err_ioremap:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	free_netdev(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
err_alloc_etherdev:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	pci_release_selected_regions(pdev, bars);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
err_pci_reg:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
err_dma:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	pci_disable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
 * e1000_remove - Device Removal Routine
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
 * @pdev: PCI device information struct
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 * e1000_remove is called by the PCI subsystem to alert the driver
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * that it should release a PCI device.  The could be caused by a
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * Hot-Plug event, or because the driver is going to be removed from
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 * memory.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
static void __devexit e1000_remove(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	cancel_work_sync(&adapter->reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	e1000_release_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	 * would have already happened in close and is redundant. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	for (i = 0; i < adapter->num_rx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		dev_put(&adapter->polling_netdev[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	unregister_netdev(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	if (!e1000_check_phy_reset_block(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		e1000_phy_hw_reset(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	kfree(adapter->tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	kfree(adapter->rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	kfree(adapter->polling_netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	iounmap(hw->hw_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	if (hw->flash_address)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		iounmap(hw->flash_address);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	pci_release_selected_regions(pdev, adapter->bars);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	free_netdev(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	pci_disable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
 * @adapter: board private structure to initialize
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
 * e1000_sw_init initializes the Adapter private data structure.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 * Fields are initialized based on PCI device information and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 * OS network device settings (MTU size).
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	/* PCI config space info */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	hw->vendor_id = pdev->vendor;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	hw->device_id = pdev->device;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	hw->subsystem_id = pdev->subsystem_device;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	hw->revision_id = pdev->revision;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	hw->max_frame_size = netdev->mtu +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	/* identify the MAC */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	if (e1000_set_mac_type(hw)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		return -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	case e1000_82541:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	case e1000_82547:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	case e1000_82541_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	case e1000_82547_rev_2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		hw->phy_init_script = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	e1000_set_media_type(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	hw->wait_autoneg_complete = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	hw->tbi_compatibility_en = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	hw->adaptive_ifs = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	/* Copper options */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	if (hw->media_type == e1000_media_type_copper) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
		hw->mdix = AUTO_ALL_MODES;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
		hw->disable_polarity_correction = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		hw->master_slave = E1000_MASTER_SLAVE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	adapter->num_tx_queues = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	adapter->num_rx_queues = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	if (e1000_alloc_queues(adapter)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	for (i = 0; i < adapter->num_rx_queues; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		adapter->polling_netdev[i].priv = adapter;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		dev_hold(&adapter->polling_netdev[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	spin_lock_init(&adapter->tx_queue_lock);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	/* Explicitly disable IRQ since the NIC can be in any state. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	e1000_irq_disable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	spin_lock_init(&adapter->stats_lock);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	set_bit(__E1000_DOWN, &adapter->flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 * e1000_alloc_queues - Allocate memory for all rings
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 * @adapter: board private structure to initialize
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 * We allocate one ring per queue at run-time since we don't know the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 * number of queues at compile-time.  The polling_netdev array is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 * intended for Multiqueue, but should work fine with a single queue.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	if (!adapter->tx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	if (!adapter->rx_ring) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		kfree(adapter->tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	                                  sizeof(struct net_device),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	                                  GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	if (!adapter->polling_netdev) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		kfree(adapter->tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		kfree(adapter->rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	return E1000_SUCCESS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
 * e1000_open - Called when a network interface is made active
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
 * Returns 0 on success, negative value on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
 * The open entry point is called when a network interface is made
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
 * active by the system (IFF_UP).  At this point all resources needed
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 * for transmit and receive operations are allocated, the interrupt
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 * handler is registered with the OS, the watchdog timer is started,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
 * and the stack is notified that the interface is ready.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
static int e1000_open(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	int err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	/* disallow open during test */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	if (test_bit(__E1000_TESTING, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		return -EBUSY;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	/* allocate transmit descriptors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	err = e1000_setup_all_tx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
		goto err_setup_tx;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	/* allocate receive descriptors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	err = e1000_setup_all_rx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		goto err_setup_rx;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	e1000_power_up_phy(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	if ((hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		e1000_update_mng_vlan(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	/* If AMT is enabled, let the firmware know that the network
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	 * interface is now open */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	if (hw->mac_type == e1000_82573 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	    e1000_check_mng_mode(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
		e1000_get_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	/* before we allocate an interrupt, we must be ready to handle it.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	 * as soon as we call pci_request_irq, so we have to setup our
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	 * clean_rx handler before we do so.  */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	e1000_configure(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	err = e1000_request_irq(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		goto err_req_irq;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	/* From here on the code is the same as e1000_up() */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	clear_bit(__E1000_DOWN, &adapter->flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	napi_enable(&adapter->napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	netif_start_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	/* fire a link status change interrupt to start the watchdog */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	ew32(ICS, E1000_ICS_LSC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	return E1000_SUCCESS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
err_req_irq:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	e1000_power_down_phy(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	e1000_free_all_rx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
err_setup_rx:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	e1000_free_all_tx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
err_setup_tx:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
 * e1000_close - Disables a network interface
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
 * Returns 0, this is not allowed to fail
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
 * The close entry point is called when an interface is de-activated
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
 * by the OS.  The hardware is still under the drivers control, but
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
 * needs to be disabled.  A global MAC reset is issued to stop the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
 * hardware, and all transmit and receive resources are freed.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
static int e1000_close(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	e1000_down(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	e1000_power_down_phy(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	e1000_free_irq(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	e1000_free_all_tx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	e1000_free_all_rx_resources(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	/* kill manageability vlan ID if supported, but not if a vlan with
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	 * the same ID is registered on the host OS (let 8021q kill it) */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	if ((hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	     !(adapter->vlgrp &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	/* If AMT is enabled, let the firmware know that the network
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	 * interface is now closed */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	if (hw->mac_type == e1000_82573 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	    e1000_check_mng_mode(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
 * @start: address of beginning of memory
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
 * @len: length of memory
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
				  unsigned long len)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	unsigned long begin = (unsigned long)start;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	unsigned long end = begin + len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	/* First rev 82545 and 82546 need to not allow any memory
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	 * write location to cross 64k boundary due to errata 23 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	if (hw->mac_type == e1000_82545 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	    hw->mac_type == e1000_82546) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	return true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
 * @txdr:    tx descriptor ring (for a specific queue) to setup
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
 * Return 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
				    struct e1000_tx_ring *txdr)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	int size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	size = sizeof(struct e1000_buffer) * txdr->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	txdr->buffer_info = vmalloc(size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	if (!txdr->buffer_info) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		"Unable to allocate memory for the transmit descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	memset(txdr->buffer_info, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	/* round up to nearest 4K */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	txdr->size = ALIGN(txdr->size, 4096);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	if (!txdr->desc) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
setup_tx_desc_die:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		vfree(txdr->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		"Unable to allocate memory for the transmit descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	/* Fix for errata 23, can't cross 64kB boundary */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		void *olddesc = txdr->desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		dma_addr_t olddma = txdr->dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
				     "at %p\n", txdr->size, txdr->desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		/* Try again, without freeing the previous */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		/* Failed allocation, critical failure */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		if (!txdr->desc) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
			goto setup_tx_desc_die;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
			/* give up */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			pci_free_consistent(pdev, txdr->size, txdr->desc,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
					    txdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
			DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
				"Unable to allocate aligned memory "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
				"for the transmit descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
			vfree(txdr->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
			return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
			/* Free old allocation, new allocation was successful */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	memset(txdr->desc, 0, txdr->size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	txdr->next_to_use = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	txdr->next_to_clean = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	spin_lock_init(&txdr->tx_lock);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
 * 				  (Descriptors) for all queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
 * Return 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	int i, err = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	for (i = 0; i < adapter->num_tx_queues; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
				"Allocation for Tx Queue %u failed\n", i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
			for (i-- ; i >= 0; i--)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
				e1000_free_tx_resources(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
							&adapter->tx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
 * Configure the Tx unit of the MAC after a reset.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
static void e1000_configure_tx(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	u64 tdba;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	u32 tdlen, tctl, tipg, tarc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	u32 ipgr1, ipgr2;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	/* Setup the HW Tx Head and Tail descriptor pointers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	switch (adapter->num_tx_queues) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	case 1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		tdba = adapter->tx_ring[0].dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		tdlen = adapter->tx_ring[0].count *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
			sizeof(struct e1000_tx_desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		ew32(TDLEN, tdlen);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		ew32(TDBAH, (tdba >> 32));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		ew32(TDT, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		ew32(TDH, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	/* Set the default values for the Tx Inter Packet Gap timer */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	if (hw->mac_type <= e1000_82547_rev_2 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	    (hw->media_type == e1000_media_type_fiber ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	     hw->media_type == e1000_media_type_internal_serdes))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	case e1000_82542_rev2_0:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	case e1000_82542_rev2_1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		tipg = DEFAULT_82542_TIPG_IPGT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	ew32(TIPG, tipg);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	/* Set the Tx Interrupt Delay register */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	ew32(TIDV, adapter->tx_int_delay);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	if (hw->mac_type >= e1000_82540)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		ew32(TADV, adapter->tx_abs_int_delay);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	/* Program the Transmit Control Register */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	tctl = er32(TCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	tctl &= ~E1000_TCTL_CT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		tarc = er32(TARC0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		/* set the speed mode bit, we'll clear it if we're not at
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		 * gigabit link later */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		tarc |= (1 << 21);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
		ew32(TARC0, tarc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	} else if (hw->mac_type == e1000_80003es2lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		tarc = er32(TARC0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		tarc |= 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		ew32(TARC0, tarc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		tarc = er32(TARC1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		tarc |= 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		ew32(TARC1, tarc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	e1000_config_collision_dist(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	/* Setup Transmit Descriptor Settings for eop descriptor */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
	/* only set IDE if we are delaying interrupts using the timers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	if (adapter->tx_int_delay)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	if (hw->mac_type < e1000_82543)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	/* Cache if we're 82544 running in PCI-X because we'll
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	 * need this to apply a workaround later in the send path. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	if (hw->mac_type == e1000_82544 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	    hw->bus_type == e1000_bus_type_pcix)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		adapter->pcix_82544 = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	ew32(TCTL, tctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
 * Returns 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
				    struct e1000_rx_ring *rxdr)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	int size, desc_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	size = sizeof(struct e1000_buffer) * rxdr->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	rxdr->buffer_info = vmalloc(size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	if (!rxdr->buffer_info) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		"Unable to allocate memory for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	memset(rxdr->buffer_info, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	rxdr->ps_page = kcalloc(rxdr->count, sizeof(struct e1000_ps_page),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
	                        GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	if (!rxdr->ps_page) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
		vfree(rxdr->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		"Unable to allocate memory for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	rxdr->ps_page_dma = kcalloc(rxdr->count,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	                            sizeof(struct e1000_ps_page_dma),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	                            GFP_KERNEL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	if (!rxdr->ps_page_dma) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		vfree(rxdr->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		kfree(rxdr->ps_page);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		"Unable to allocate memory for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	if (hw->mac_type <= e1000_82547_rev_2)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		desc_len = sizeof(struct e1000_rx_desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		desc_len = sizeof(union e1000_rx_desc_packet_split);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	/* Round up to nearest 4K */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	rxdr->size = rxdr->count * desc_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	rxdr->size = ALIGN(rxdr->size, 4096);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	if (!rxdr->desc) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
		DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		"Unable to allocate memory for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
setup_rx_desc_die:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		vfree(rxdr->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
		kfree(rxdr->ps_page);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		kfree(rxdr->ps_page_dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		return -ENOMEM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	/* Fix for errata 23, can't cross 64kB boundary */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		void *olddesc = rxdr->desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		dma_addr_t olddma = rxdr->dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
				     "at %p\n", rxdr->size, rxdr->desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		/* Try again, without freeing the previous */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		/* Failed allocation, critical failure */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		if (!rxdr->desc) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
			DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
				"Unable to allocate memory "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
				"for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
			goto setup_rx_desc_die;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			/* give up */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
					    rxdr->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
			DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
				"Unable to allocate aligned memory "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
				"for the receive descriptor ring\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			goto setup_rx_desc_die;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
			/* Free old allocation, new allocation was successful */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	memset(rxdr->desc, 0, rxdr->size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	rxdr->next_to_clean = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	rxdr->next_to_use = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * 				  (Descriptors) for all queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * Return 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	int i, err = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	for (i = 0; i < adapter->num_rx_queues; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
			DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
				"Allocation for Rx Queue %u failed\n", i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
			for (i-- ; i >= 0; i--)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
				e1000_free_rx_resources(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
							&adapter->rx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 * e1000_setup_rctl - configure the receive control registers
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * @adapter: Board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
static void e1000_setup_rctl(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	u32 rctl, rfctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	u32 psrctl = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	u32 pages = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	if (hw->tbi_compatibility_on == 1)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		rctl |= E1000_RCTL_SBP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		rctl &= ~E1000_RCTL_SBP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		rctl &= ~E1000_RCTL_LPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		rctl |= E1000_RCTL_LPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	/* Setup buffer sizes */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	rctl &= ~E1000_RCTL_SZ_4096;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	rctl |= E1000_RCTL_BSEX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	switch (adapter->rx_buffer_len) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		case E1000_RXBUFFER_256:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			rctl |= E1000_RCTL_SZ_256;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
			rctl &= ~E1000_RCTL_BSEX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		case E1000_RXBUFFER_512:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
			rctl |= E1000_RCTL_SZ_512;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
			rctl &= ~E1000_RCTL_BSEX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		case E1000_RXBUFFER_1024:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
			rctl |= E1000_RCTL_SZ_1024;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
			rctl &= ~E1000_RCTL_BSEX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		case E1000_RXBUFFER_2048:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
			rctl |= E1000_RCTL_SZ_2048;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			rctl &= ~E1000_RCTL_BSEX;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		case E1000_RXBUFFER_4096:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
			rctl |= E1000_RCTL_SZ_4096;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		case E1000_RXBUFFER_8192:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
			rctl |= E1000_RCTL_SZ_8192;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		case E1000_RXBUFFER_16384:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
			rctl |= E1000_RCTL_SZ_16384;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	/* 82571 and greater support packet-split where the protocol
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	 * header is placed in skb->data and the packet data is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	 * In the case of a non-split, skb->data is linearly filled,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	 * followed by the page buffers.  Therefore, skb->data is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	 * sized to hold the largest protocol header.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	/* allocations using alloc_page take too long for regular MTU
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	 * so only enable packet split for jumbo frames */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	if ((hw->mac_type >= e1000_82571) && (pages <= 3) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	    PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
		adapter->rx_ps_pages = pages;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
		adapter->rx_ps_pages = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	if (adapter->rx_ps_pages) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		/* Configure extra packet-split registers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		rfctl = er32(RFCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		rfctl |= E1000_RFCTL_EXTEN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		/* disable packet split support for IPv6 extension headers,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		 * because some malformed IPv6 headers can hang the RX */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		          E1000_RFCTL_NEW_IPV6_EXT_DIS);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		ew32(RFCTL, rfctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		rctl |= E1000_RCTL_DTYP_PS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		psrctl |= adapter->rx_ps_bsize0 >>
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			E1000_PSRCTL_BSIZE0_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		switch (adapter->rx_ps_pages) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
		case 3:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			psrctl |= PAGE_SIZE <<
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
				E1000_PSRCTL_BSIZE3_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		case 2:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
			psrctl |= PAGE_SIZE <<
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
				E1000_PSRCTL_BSIZE2_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
		case 1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
			psrctl |= PAGE_SIZE >>
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
				E1000_PSRCTL_BSIZE1_SHIFT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		ew32(PSRCTL, psrctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 * Configure the Rx unit of the MAC after a reset.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
static void e1000_configure_rx(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
	u64 rdba;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	u32 rdlen, rctl, rxcsum, ctrl_ext;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	if (adapter->rx_ps_pages) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
		/* this is a 32 byte descriptor */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		rdlen = adapter->rx_ring[0].count *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			sizeof(union e1000_rx_desc_packet_split);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		adapter->clean_rx = e1000_clean_rx_irq_ps;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		rdlen = adapter->rx_ring[0].count *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
			sizeof(struct e1000_rx_desc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		adapter->clean_rx = e1000_clean_rx_irq;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	/* disable receives while setting up the descriptors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	/* set the Receive Delay Timer Register */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	ew32(RDTR, adapter->rx_int_delay);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	if (hw->mac_type >= e1000_82540) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
		ew32(RADV, adapter->rx_abs_int_delay);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
		if (adapter->itr_setting != 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
			ew32(ITR, 1000000000 / (adapter->itr * 256));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	if (hw->mac_type >= e1000_82571) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		ctrl_ext = er32(CTRL_EXT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		/* Reset delay timers after every interrupt */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
		/* Auto-Mask interrupts upon ICR access */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
		ctrl_ext |= E1000_CTRL_EXT_IAME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		ew32(IAM, 0xffffffff);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
		ew32(CTRL_EXT, ctrl_ext);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
		E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	 * the Base and Length of the Rx Descriptor Ring */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	switch (adapter->num_rx_queues) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	case 1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		rdba = adapter->rx_ring[0].dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
		ew32(RDLEN, rdlen);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		ew32(RDBAH, (rdba >> 32));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		ew32(RDT, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		ew32(RDH, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	if (hw->mac_type >= e1000_82543) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		rxcsum = er32(RXCSUM);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		if (adapter->rx_csum) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			rxcsum |= E1000_RXCSUM_TUOFL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
			/* Enable 82571 IPv4 payload checksum for UDP fragments
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			 * Must be used in conjunction with packet-split. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			if ((hw->mac_type >= e1000_82571) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			    (adapter->rx_ps_pages)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
				rxcsum |= E1000_RXCSUM_IPPCSE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			rxcsum &= ~E1000_RXCSUM_TUOFL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			/* don't need to clear IPPCSE as it defaults to 0 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
		ew32(RXCSUM, rxcsum);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
	/* enable early receives on 82573, only takes effect if using > 2048
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	 * byte total frame size.  for example only for jumbo frames */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
#define E1000_ERT_2048 0x100
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	if (hw->mac_type == e1000_82573)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
		ew32(ERT, E1000_ERT_2048);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	/* Enable Receives */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
 * e1000_free_tx_resources - Free Tx Resources per Queue
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 * @tx_ring: Tx descriptor ring for a specific queue
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 * Free all transmit software resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
				    struct e1000_tx_ring *tx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	e1000_clean_tx_ring(adapter, tx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	vfree(tx_ring->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	tx_ring->buffer_info = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	tx_ring->desc = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
 * Free all transmit software resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	for (i = 0; i < adapter->num_tx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
					     struct e1000_buffer *buffer_info)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	if (buffer_info->dma) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		pci_unmap_page(adapter->pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
				buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
				buffer_info->length,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
				PCI_DMA_TODEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		buffer_info->dma = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	if (buffer_info->skb) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		dev_kfree_skb_any(buffer_info->skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		buffer_info->skb = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	/* buffer_info must be completely set up in the transmit path */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
 * e1000_clean_tx_ring - Free Tx Buffers
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
 * @tx_ring: ring to be cleaned
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
				struct e1000_tx_ring *tx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	unsigned long size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	/* Free all the Tx ring sk_buffs */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	for (i = 0; i < tx_ring->count; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
		buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	size = sizeof(struct e1000_buffer) * tx_ring->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	memset(tx_ring->buffer_info, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	/* Zero out the descriptor ring */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	memset(tx_ring->desc, 0, tx_ring->size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	tx_ring->next_to_use = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	tx_ring->next_to_clean = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	tx_ring->last_tx_tso = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	writel(0, hw->hw_addr + tx_ring->tdh);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	writel(0, hw->hw_addr + tx_ring->tdt);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	for (i = 0; i < adapter->num_tx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
 * e1000_free_rx_resources - Free Rx Resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
 * @rx_ring: ring to clean the resources from
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
 * Free all receive software resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
				    struct e1000_rx_ring *rx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	e1000_clean_rx_ring(adapter, rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	vfree(rx_ring->buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	rx_ring->buffer_info = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	kfree(rx_ring->ps_page);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	rx_ring->ps_page = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	kfree(rx_ring->ps_page_dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	rx_ring->ps_page_dma = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	rx_ring->desc = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
 * Free all receive software resources
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	for (i = 0; i < adapter->num_rx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 * @rx_ring: ring to free buffers from
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
				struct e1000_rx_ring *rx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	struct e1000_ps_page *ps_page;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	struct e1000_ps_page_dma *ps_page_dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	unsigned long size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	unsigned int i, j;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	/* Free all the Rx ring sk_buffs */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	for (i = 0; i < rx_ring->count; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
		buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
		if (buffer_info->skb) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
			pci_unmap_single(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
					 buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
					 buffer_info->length,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
					 PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
			dev_kfree_skb(buffer_info->skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
			buffer_info->skb = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		ps_page = &rx_ring->ps_page[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		ps_page_dma = &rx_ring->ps_page_dma[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
		for (j = 0; j < adapter->rx_ps_pages; j++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
			if (!ps_page->ps_page[j]) break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			pci_unmap_page(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
				       ps_page_dma->ps_page_dma[j],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
				       PAGE_SIZE, PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
			ps_page_dma->ps_page_dma[j] = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
			put_page(ps_page->ps_page[j]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
			ps_page->ps_page[j] = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	size = sizeof(struct e1000_buffer) * rx_ring->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	memset(rx_ring->buffer_info, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	size = sizeof(struct e1000_ps_page) * rx_ring->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	memset(rx_ring->ps_page, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	memset(rx_ring->ps_page_dma, 0, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	/* Zero out the descriptor ring */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	memset(rx_ring->desc, 0, rx_ring->size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	rx_ring->next_to_clean = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	rx_ring->next_to_use = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	writel(0, hw->hw_addr + rx_ring->rdh);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	writel(0, hw->hw_addr + rx_ring->rdt);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	for (i = 0; i < adapter->num_rx_queues; i++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
 * and memory write and invalidate disabled for certain operations
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	u32 rctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	e1000_pci_clear_mwi(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	rctl |= E1000_RCTL_RST;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	mdelay(5);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	if (netif_running(netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
		e1000_clean_all_rx_rings(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	u32 rctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	rctl &= ~E1000_RCTL_RST;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	mdelay(5);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		e1000_pci_set_mwi(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	if (netif_running(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
		/* No need to loop, because 82542 supports only 1 queue */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		e1000_configure_rx(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
 * e1000_set_mac - Change the Ethernet Address of the NIC
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
 * @p: pointer to an address structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
 * Returns 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
static int e1000_set_mac(struct net_device *netdev, void *p)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	struct sockaddr *addr = p;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	if (!is_valid_ether_addr(addr->sa_data))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		return -EADDRNOTAVAIL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	/* 82542 2.0 needs to be in reset to write receive address registers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	if (hw->mac_type == e1000_82542_rev2_0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
		e1000_enter_82542_rst(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	e1000_rar_set(hw, hw->mac_addr, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	/* With 82571 controllers, LAA may be overwritten (with the default)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	 * due to controller reset from the other port. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	if (hw->mac_type == e1000_82571) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		/* activate the work around */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		hw->laa_is_present = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		/* Hold a copy of the LAA in RAR[14] This is done so that
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		 * between the time RAR[0] gets clobbered  and the time it
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		 * of the RARs and no incoming packets directed to this port
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
		 * are dropped. Eventaully the LAA will be in RAR[0] and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		 * RAR[14] */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
		e1000_rar_set(hw, hw->mac_addr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
					E1000_RAR_ENTRIES - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
	if (hw->mac_type == e1000_82542_rev2_0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
		e1000_leave_82542_rst(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
 * The set_rx_mode entry point is called whenever the unicast or multicast
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
 * address lists or the network interface flags are updated. This routine is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
 * responsible for configuring the hardware for proper unicast, multicast,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
 * promiscuous mode, and all-multi behavior.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
static void e1000_set_rx_mode(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	struct dev_addr_list *uc_ptr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	struct dev_addr_list *mc_ptr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	u32 rctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	u32 hash_value;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	int i, rar_entries = E1000_RAR_ENTRIES;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
				E1000_NUM_MTA_REGISTERS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	if (hw->mac_type == e1000_ich8lan)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	/* reserve RAR[14] for LAA over-write work-around */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	if (hw->mac_type == e1000_82571)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		rar_entries--;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	/* Check for Promiscuous and All Multicast modes */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	if (netdev->flags & IFF_PROMISC) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		rctl &= ~E1000_RCTL_VFE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		if (netdev->flags & IFF_ALLMULTI) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
			rctl |= E1000_RCTL_MPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
			rctl &= ~E1000_RCTL_MPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		if (adapter->hw.mac_type != e1000_ich8lan)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			rctl |= E1000_RCTL_VFE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	uc_ptr = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
	if (netdev->uc_count > rar_entries - 1) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		rctl |= E1000_RCTL_UPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	} else if (!(netdev->flags & IFF_PROMISC)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		rctl &= ~E1000_RCTL_UPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		uc_ptr = netdev->uc_list;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	/* 82542 2.0 needs to be in reset to write receive address registers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	if (hw->mac_type == e1000_82542_rev2_0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		e1000_enter_82542_rst(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	/* load the first 14 addresses into the exact filters 1-14. Unicast
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	 * addresses take precedence to avoid disabling unicast filtering
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	 * when possible.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	 * RAR 0 is used for the station MAC adddress
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	 * if there are not 14 addresses, go ahead and clear the filters
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	 * -- with 82571 controllers only 0-13 entries are filled here
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	mc_ptr = netdev->mc_list;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	for (i = 1; i < rar_entries; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		if (uc_ptr) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			e1000_rar_set(hw, uc_ptr->da_addr, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			uc_ptr = uc_ptr->next;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		} else if (mc_ptr) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			e1000_rar_set(hw, mc_ptr->da_addr, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			mc_ptr = mc_ptr->next;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	WARN_ON(uc_ptr != NULL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	/* clear the old settings from the multicast hash table */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
	for (i = 0; i < mta_reg_count; i++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	/* load any remaining addresses into the hash table */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		e1000_mta_set(hw, hash_value);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	if (hw->mac_type == e1000_82542_rev2_0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		e1000_leave_82542_rst(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
/* Need to wait a few seconds after link up to get diagnostic information from
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
 * the phy */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
static void e1000_update_phy_info(unsigned long data)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	e1000_phy_get_info(hw, &adapter->phy_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
 * e1000_82547_tx_fifo_stall - Timer Call-back
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
 * @data: pointer to adapter cast into an unsigned long
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
static void e1000_82547_tx_fifo_stall(unsigned long data)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	u32 tctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	if (atomic_read(&adapter->tx_fifo_stall)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		if ((er32(TDT) == er32(TDH)) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		   (er32(TDFT) == er32(TDFH)) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		   (er32(TDFTS) == er32(TDFHS))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			tctl = er32(TCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			ew32(TDFT, adapter->tx_head_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			ew32(TDFH, adapter->tx_head_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			ew32(TDFTS, adapter->tx_head_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
			ew32(TDFHS, adapter->tx_head_addr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
			ew32(TCTL, tctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
			E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
			adapter->tx_fifo_head = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			atomic_set(&adapter->tx_fifo_stall, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
			netif_wake_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
 * e1000_watchdog - Timer Call-back
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
 * @data: pointer to adapter cast into an unsigned long
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
static void e1000_watchdog(unsigned long data)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	struct e1000_tx_ring *txdr = adapter->tx_ring;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	u32 link, tctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	s32 ret_val;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	ret_val = e1000_check_for_link(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	if ((ret_val == E1000_ERR_PHY) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	    (hw->phy_type == e1000_phy_igp_3) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
		/* See e1000_kumeran_lock_loss_workaround() */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		DPRINTK(LINK, INFO,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
			"Gigabit has been disabled, downgrading speed\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	if (hw->mac_type == e1000_82573) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		e1000_enable_tx_pkt_filtering(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		if (adapter->mng_vlan_id != hw->mng_cookie.vlan_id)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
			e1000_update_mng_vlan(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	if ((hw->media_type == e1000_media_type_internal_serdes) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	   !(er32(TXCW) & E1000_TXCW_ANE))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
		link = !hw->serdes_link_down;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
		link = er32(STATUS) & E1000_STATUS_LU;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	if (link) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		if (!netif_carrier_ok(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			u32 ctrl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
			bool txb2b = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
			e1000_get_speed_and_duplex(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
			                           &adapter->link_speed,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			                           &adapter->link_duplex);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			ctrl = er32(CTRL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s, "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
			        "Flow Control: %s\n",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
			        adapter->link_speed,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
			        adapter->link_duplex == FULL_DUPLEX ?
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
			        "Full Duplex" : "Half Duplex",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
			/* tweak tx_queue_len according to speed/duplex
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
			 * and adjust the timeout factor */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
			netdev->tx_queue_len = adapter->tx_queue_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
			adapter->tx_timeout_factor = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			switch (adapter->link_speed) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
			case SPEED_10:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
				txb2b = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
				netdev->tx_queue_len = 10;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
				adapter->tx_timeout_factor = 8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
			case SPEED_100:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
				txb2b = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
				netdev->tx_queue_len = 100;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
				/* maybe add some timeout factor ? */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
			if ((hw->mac_type == e1000_82571 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
			     hw->mac_type == e1000_82572) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
			    !txb2b) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
				u32 tarc0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
				tarc0 = er32(TARC0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
				tarc0 &= ~(1 << 21);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
				ew32(TARC0, tarc0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
			/* disable TSO for pcie and 10/100 speeds, to avoid
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
			 * some hardware issues */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			if (!adapter->tso_force &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			    hw->bus_type == e1000_bus_type_pci_express){
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
				switch (adapter->link_speed) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
				case SPEED_10:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
				case SPEED_100:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
					DPRINTK(PROBE,INFO,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
				        "10/100 speed: disabling TSO\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
					netdev->features &= ~NETIF_F_TSO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
					netdev->features &= ~NETIF_F_TSO6;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
				case SPEED_1000:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
					netdev->features |= NETIF_F_TSO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
					netdev->features |= NETIF_F_TSO6;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
				default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
					/* oops */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
			/* enable transmits in the hardware, need to do this
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
			 * after setting TARC0 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
			tctl = er32(TCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			tctl |= E1000_TCTL_EN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			ew32(TCTL, tctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
			netif_carrier_on(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			netif_wake_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
			adapter->smartspeed = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
			/* make sure the receive unit is started */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
			if (hw->rx_needs_kicking) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
				u32 rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
				ew32(RCTL, rctl | E1000_RCTL_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		if (netif_carrier_ok(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
			adapter->link_speed = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
			adapter->link_duplex = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
			DPRINTK(LINK, INFO, "NIC Link is Down\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
			netif_carrier_off(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
			netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
			/* 80003ES2LAN workaround--
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
			 * For packet buffer work-around on link down event;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
			 * disable receives in the ISR and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
			 * reset device here in the watchdog
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
			 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
			if (hw->mac_type == e1000_80003es2lan)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
				/* reset device */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
				schedule_work(&adapter->reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		e1000_smartspeed(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	e1000_update_stats(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	adapter->tpt_old = adapter->stats.tpt;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	adapter->colc_old = adapter->stats.colc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	adapter->gorcl_old = adapter->stats.gorcl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	adapter->gotcl_old = adapter->stats.gotcl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	e1000_update_adaptive(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	if (!netif_carrier_ok(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			/* We've lost link, so the controller stops DMA,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			 * but we've got queued Tx work that's never going
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
			 * to get done, so reset controller to flush Tx.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
			 * (Do the reset outside of interrupt context). */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
			adapter->tx_timeout_count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
			schedule_work(&adapter->reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	/* Cause software interrupt to ensure rx ring is cleaned */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	ew32(ICS, E1000_ICS_RXDMT0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	/* Force detection of hung controller every watchdog period */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	adapter->detect_tx_hung = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	/* With 82571 controllers, LAA may be overwritten due to controller
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
	if (hw->mac_type == e1000_82571 && hw->laa_is_present)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		e1000_rar_set(hw, hw->mac_addr, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	/* Reset the timer */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
enum latency_range {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	lowest_latency = 0,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	low_latency = 1,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	bulk_latency = 2,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	latency_invalid = 255
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
};
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
 * e1000_update_itr - update the dynamic ITR value based on statistics
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
 *      Stores a new ITR value based on packets and byte
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
 *      counts during the last interrupt.  The advantage of per interrupt
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
 *      computation is faster updates and more accurate ITR for the current
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
 *      traffic pattern.  Constants in this function were computed
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
 *      based on theoretical maximum wire speed and thresholds were set based
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
 *      on testing data as well as attempting to minimize response time
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
 *      while increasing bulk throughput.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
 *      this functionality is controlled by the InterruptThrottleRate module
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
 *      parameter (see e1000_param.c)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
 * @adapter: pointer to adapter
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
 * @itr_setting: current adapter->itr
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
 * @packets: the number of packets during this measurement interval
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
 * @bytes: the number of bytes during this measurement interval
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
				     u16 itr_setting, int packets, int bytes)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	unsigned int retval = itr_setting;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	if (unlikely(hw->mac_type < e1000_82540))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		goto update_itr_done;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	if (packets == 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		goto update_itr_done;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	switch (itr_setting) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	case lowest_latency:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
		/* jumbo frames get bulk treatment*/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		if (bytes/packets > 8000)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
			retval = bulk_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
		else if ((packets < 5) && (bytes > 512))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
			retval = low_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	case low_latency:  /* 50 usec aka 20000 ints/s */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		if (bytes > 10000) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
			/* jumbo frames need bulk latency setting */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
			if (bytes/packets > 8000)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
				retval = bulk_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
			else if ((packets < 10) || ((bytes/packets) > 1200))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
				retval = bulk_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			else if ((packets > 35))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
				retval = lowest_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		} else if (bytes/packets > 2000)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
			retval = bulk_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		else if (packets <= 2 && bytes < 512)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
			retval = lowest_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	case bulk_latency: /* 250 usec aka 4000 ints/s */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		if (bytes > 25000) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			if (packets > 35)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
				retval = low_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		} else if (bytes < 6000) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
			retval = low_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
update_itr_done:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
	return retval;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
static void e1000_set_itr(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	u16 current_itr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	u32 new_itr = adapter->itr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	if (unlikely(hw->mac_type < e1000_82540))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	if (unlikely(adapter->link_speed != SPEED_1000)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		current_itr = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		new_itr = 4000;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		goto set_itr_now;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	adapter->tx_itr = e1000_update_itr(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	                            adapter->tx_itr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	                            adapter->total_tx_packets,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	                            adapter->total_tx_bytes);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
		adapter->tx_itr = low_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	adapter->rx_itr = e1000_update_itr(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	                            adapter->rx_itr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	                            adapter->total_rx_packets,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	                            adapter->total_rx_bytes);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		adapter->rx_itr = low_latency;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	switch (current_itr) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	/* counts and packets in update_itr are dependent on these numbers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	case lowest_latency:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		new_itr = 70000;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	case low_latency:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		new_itr = 20000; /* aka hwitr = ~200 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	case bulk_latency:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		new_itr = 4000;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
set_itr_now:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	if (new_itr != adapter->itr) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		/* this attempts to bias the interrupt rate towards Bulk
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		 * by adding intermediate steps when interrupt rate is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		 * increasing */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		new_itr = new_itr > adapter->itr ?
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		             min(adapter->itr + (new_itr >> 2), new_itr) :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		             new_itr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		adapter->itr = new_itr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		ew32(ITR, 1000000000 / (new_itr * 256));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
#define E1000_TX_FLAGS_CSUM		0x00000001
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
#define E1000_TX_FLAGS_VLAN		0x00000002
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
#define E1000_TX_FLAGS_TSO		0x00000004
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
#define E1000_TX_FLAGS_IPV4		0x00000008
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
#define E1000_TX_FLAGS_VLAN_SHIFT	16
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
static int e1000_tso(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	struct e1000_context_desc *context_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	u32 cmd_length = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	u16 ipcse = 0, tucse, mss;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	int err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	if (skb_is_gso(skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		if (skb_header_cloned(skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
			if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
				return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		mss = skb_shinfo(skb)->gso_size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		if (skb->protocol == htons(ETH_P_IP)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
			struct iphdr *iph = ip_hdr(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
			iph->tot_len = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
			iph->check = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
								 iph->daddr, 0,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
								 IPPROTO_TCP,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
								 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
			cmd_length = E1000_TXD_CMD_IP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
			ipcse = skb_transport_offset(skb) - 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
			ipv6_hdr(skb)->payload_len = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
			tcp_hdr(skb)->check =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
						 &ipv6_hdr(skb)->daddr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
						 0, IPPROTO_TCP, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
			ipcse = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		ipcss = skb_network_offset(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		tucss = skb_transport_offset(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		tucse = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		i = tx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
		context_desc->upper_setup.tcp_fields.tucss = tucss;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
		context_desc->upper_setup.tcp_fields.tucso = tucso;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		buffer_info->time_stamp = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		buffer_info->next_to_watch = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		if (++i == tx_ring->count) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		tx_ring->next_to_use = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		return true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	return false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
static bool e1000_tx_csum(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	struct e1000_context_desc *context_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	u8 css;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		css = skb_transport_offset(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		i = tx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		context_desc->lower_setup.ip_config = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
		context_desc->upper_setup.tcp_fields.tucss = css;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
		context_desc->upper_setup.tcp_fields.tucso =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			css + skb->csum_offset;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
		context_desc->upper_setup.tcp_fields.tucse = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		context_desc->tcp_seg_setup.data = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
		buffer_info->time_stamp = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		buffer_info->next_to_watch = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		if (unlikely(++i == tx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		tx_ring->next_to_use = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		return true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	return false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
#define E1000_MAX_TXD_PWR	12
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
static int e1000_tx_map(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
			struct e1000_tx_ring *tx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			struct sk_buff *skb, unsigned int first,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
			unsigned int max_per_txd, unsigned int nr_frags,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			unsigned int mss)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	unsigned int len = skb->len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	unsigned int offset = 0, size, count = 0, i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	unsigned int f;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	len -= skb->data_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	i = tx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	while (len) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		size = min(len, max_per_txd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		/* Workaround for Controller erratum --
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		 * descriptor for non-tso packet in a linear SKB that follows a
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		 * tso gets written back prematurely before the data is fully
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		 * DMA'd to the controller */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
		if (!skb->data_len && tx_ring->last_tx_tso &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		    !skb_is_gso(skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
			tx_ring->last_tx_tso = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
			size -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		/* Workaround for premature desc write-backs
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		 * in TSO mode.  Append 4-byte sentinel desc */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
		if (unlikely(mss && !nr_frags && size == len && size > 8))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
			size -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		/* work-around for errata 10 and it applies
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		 * to all controllers in PCI-X mode
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		 * The fix is to make sure that the first descriptor of a
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		                (size > 2015) && count == 0))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		        size = 2015;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
		 * terminating buffers within evenly-aligned dwords. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		if (unlikely(adapter->pcix_82544 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		   size > 4))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
			size -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		buffer_info->length = size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		buffer_info->dma =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
			pci_map_single(adapter->pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
				skb->data + offset,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
				size,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
				PCI_DMA_TODEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		buffer_info->time_stamp = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		buffer_info->next_to_watch = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
		len -= size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		offset += size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		if (unlikely(++i == tx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	for (f = 0; f < nr_frags; f++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		struct skb_frag_struct *frag;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		frag = &skb_shinfo(skb)->frags[f];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		len = frag->size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		offset = frag->page_offset;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
		while (len) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
			buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
			size = min(len, max_per_txd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
			/* Workaround for premature desc write-backs
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
			 * in TSO mode.  Append 4-byte sentinel desc */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
				size -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
			/* Workaround for potential 82544 hang in PCI-X.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
			 * Avoid terminating buffers within evenly-aligned
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
			 * dwords. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
			if (unlikely(adapter->pcix_82544 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
			   size > 4))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
				size -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
			buffer_info->length = size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
			buffer_info->dma =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
				pci_map_page(adapter->pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
					frag->page,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
					offset,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
					size,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
					PCI_DMA_TODEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
			buffer_info->time_stamp = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
			buffer_info->next_to_watch = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
			len -= size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
			offset += size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
			count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
			if (unlikely(++i == tx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	tx_ring->buffer_info[i].skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	tx_ring->buffer_info[first].next_to_watch = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	return count;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
static void e1000_tx_queue(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			   struct e1000_tx_ring *tx_ring, int tx_flags,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
			   int count)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	struct e1000_tx_desc *tx_desc = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		             E1000_TXD_CMD_TSE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		txd_lower |= E1000_TXD_CMD_VLE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	i = tx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	while (count--) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		tx_desc = E1000_TX_DESC(*tx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
		tx_desc->lower.data =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
			cpu_to_le32(txd_lower | buffer_info->length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
		tx_desc->upper.data = cpu_to_le32(txd_upper);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
		if (unlikely(++i == tx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	/* Force memory writes to complete before letting h/w
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	 * know there are new descriptors to fetch.  (Only
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	 * applicable for weak-ordered memory model archs,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	 * such as IA-64). */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	wmb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	tx_ring->next_to_use = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	writel(i, hw->hw_addr + tx_ring->tdt);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	/* we need this if more than one processor can write to our tail
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	 * at a time, it syncronizes IO on IA64/Altix systems */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	mmiowb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
 * 82547 workaround to avoid controller hang in half-duplex environment.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
 * The workaround is to avoid queuing a large packet that would span
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
 * the internal Tx FIFO ring boundary by notifying the stack to resend
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
 * to the beginning of the Tx FIFO.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
#define E1000_FIFO_HDR			0x10
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
#define E1000_82547_PAD_LEN		0x3E0
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
				       struct sk_buff *skb)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	if (adapter->link_duplex != HALF_DUPLEX)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
		goto no_fifo_stall_required;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	if (atomic_read(&adapter->tx_fifo_stall))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		return 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		atomic_set(&adapter->tx_fifo_stall, 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		return 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
no_fifo_stall_required:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	adapter->tx_fifo_head += skb_fifo_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
#define MINIMUM_DHCP_PACKET_SIZE 282
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
				    struct sk_buff *skb)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	struct e1000_hw *hw =  &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	u16 length, offset;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	if (vlan_tx_tag_present(skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
			( hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
			return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		struct ethhdr *eth = (struct ethhdr *)skb->data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
		if ((htons(ETH_P_IP) == eth->h_proto)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
			const struct iphdr *ip =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
				(struct iphdr *)((u8 *)skb->data+14);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
			if (IPPROTO_UDP == ip->protocol) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
				struct udphdr *udp =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
					(struct udphdr *)((u8 *)ip +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
						(ip->ihl << 2));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
				if (ntohs(udp->dest) == 67) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
					offset = (u8 *)udp + 8 - skb->data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
					length = skb->len - offset;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
					return e1000_mng_write_dhcp_info(hw,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
							(u8 *)udp + 8,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
							length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	/* Herbert's original patch had:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	 *  smp_mb__after_netif_stop_queue();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	 * but since that doesn't exist yet, just open code it. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	smp_mb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	/* We need to check again in a case another CPU has just
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	 * made room available. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		return -EBUSY;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	/* A reprieve! */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	netif_start_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	++adapter->restart_queue;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
static int e1000_maybe_stop_tx(struct net_device *netdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
                               struct e1000_tx_ring *tx_ring, int size)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
		return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	return __e1000_maybe_stop_tx(netdev, size);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	struct e1000_tx_ring *tx_ring;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	unsigned int tx_flags = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	unsigned int len = skb->len - skb->data_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	unsigned long flags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	unsigned int nr_frags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	unsigned int mss;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	int count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	int tso;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	unsigned int f;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	/* This goes back to the question of how to logically map a tx queue
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	 * to a flow.  Right now, performance is impacted slightly negatively
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	 * if using multiple tx queues.  If the stack breaks away from a
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	 * single qdisc implementation, we can look at this again. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	tx_ring = adapter->tx_ring;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	if (unlikely(skb->len <= 0)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		dev_kfree_skb_any(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
		return NETDEV_TX_OK;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	/* 82571 and newer doesn't need the workaround that limited descriptor
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	 * length to 4kB */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	if (hw->mac_type >= e1000_82571)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		max_per_txd = 8192;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	mss = skb_shinfo(skb)->gso_size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	/* The controller does a simple calculation to
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	 * make sure there is enough room in the FIFO before
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	 * initiating the DMA for each buffer.  The calc is:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	 * 4 = ceil(buffer len/mss).  To make sure we don't
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	 * overrun the FIFO, adjust the max buffer len if mss
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	 * drops. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	if (mss) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		u8 hdr_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		max_per_txd = min(mss << 2, max_per_txd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		max_txd_pwr = fls(max_per_txd) - 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
		* points to just header, pull a few bytes of payload from
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
		* frags into skb->data */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
		if (skb->data_len && hdr_len == len) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
			switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
				unsigned int pull_size;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
			case e1000_82544:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
				/* Make sure we have room to chop off 4 bytes,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
				 * and that the end alignment will work out to
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
				 * this hardware's requirements
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
				 * NOTE: this is a TSO only workaround
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
				 * if end byte alignment not correct move us
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
				 * into the next dword */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
				/* fall through */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
			case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
			case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
			case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
			case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
				pull_size = min((unsigned int)4, skb->data_len);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
				if (!__pskb_pull_tail(skb, pull_size)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
					DPRINTK(DRV, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
						"__pskb_pull_tail failed.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
					dev_kfree_skb_any(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
					return NETDEV_TX_OK;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
				len = skb->len - skb->data_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
			default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
				/* do nothing */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	/* reserve a descriptor for the offload context */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
		count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	/* Controller Erratum workaround */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	count += TXD_USE_COUNT(len, max_txd_pwr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	if (adapter->pcix_82544)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	/* work-around for errata 10 and it applies to all controllers
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	 * in PCI-X mode, so add one more descriptor to the count
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
			(len > 2015)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	nr_frags = skb_shinfo(skb)->nr_frags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	for (f = 0; f < nr_frags; f++)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
				       max_txd_pwr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	if (adapter->pcix_82544)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		count += nr_frags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	if (hw->tx_pkt_filtering &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	    (hw->mac_type == e1000_82573))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		e1000_transfer_dhcp_info(adapter, skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		/* Collision - tell upper layer to requeue */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
		return NETDEV_TX_LOCKED;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	/* need: count + 2 desc gap to keep tail from touching
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	 * head, otherwise try next time */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
		return NETDEV_TX_BUSY;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	if (unlikely(hw->mac_type == e1000_82547)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
			netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
			return NETDEV_TX_BUSY;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
		tx_flags |= E1000_TX_FLAGS_VLAN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	first = tx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	tso = e1000_tso(adapter, tx_ring, skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	if (tso < 0) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		dev_kfree_skb_any(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
		return NETDEV_TX_OK;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	if (likely(tso)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		tx_ring->last_tx_tso = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		tx_flags |= E1000_TX_FLAGS_TSO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		tx_flags |= E1000_TX_FLAGS_CSUM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	 * no longer assume, we must. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	if (likely(skb->protocol == htons(ETH_P_IP)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		tx_flags |= E1000_TX_FLAGS_IPV4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	e1000_tx_queue(adapter, tx_ring, tx_flags,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	               e1000_tx_map(adapter, tx_ring, skb, first,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
	                            max_per_txd, nr_frags, mss));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	netdev->trans_start = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	/* Make sure there is space in the ring for the next send. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	return NETDEV_TX_OK;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
 * e1000_tx_timeout - Respond to a Tx Hang
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
static void e1000_tx_timeout(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	/* Do the reset outside of interrupt context */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	adapter->tx_timeout_count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	schedule_work(&adapter->reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
static void e1000_reset_task(struct work_struct *work)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	struct e1000_adapter *adapter =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
		container_of(work, struct e1000_adapter, reset_task);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	e1000_reinit_locked(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
 * e1000_get_stats - Get System Network Statistics
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
 * Returns the address of the device statistics structure.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
 * The statistics are actually updated from the timer callback.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	/* only return the current stats */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	return &adapter->net_stats;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
 * e1000_change_mtu - Change the Maximum Transfer Unit
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
 * @netdev: network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
 * @new_mtu: new value for maximum frame size
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
 * Returns 0 on success, negative on failure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	u16 eeprom_data = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	/* Adapter-specific max frame size limits. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	switch (hw->mac_type) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	case e1000_undefined ... e1000_82542_rev2_1:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
	case e1000_ich8lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
			return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	case e1000_82573:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
		/* Jumbo Frames not supported if:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		 * - this is not an 82573L device
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		 * - ASPM is enabled in any way (0x1A bits 3:2) */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		e1000_read_eeprom(hw, EEPROM_INIT_3GIO_3, 1,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		                  &eeprom_data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		if ((hw->device_id != E1000_DEV_ID_82573L) ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
				DPRINTK(PROBE, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
			            	"Jumbo Frames not supported.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
				return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		/* ERT will be enabled later to enable wire speed receives */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		/* fall through to get support */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	case e1000_82571:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	case e1000_82572:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	case e1000_80003es2lan:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
#define MAX_STD_JUMBO_FRAME_SIZE 9234
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
			return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	 * means we reserve 2 more, this pushes us to allocate from the next
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	 * larger slab size
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	if (max_frame <= E1000_RXBUFFER_256)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	else if (max_frame <= E1000_RXBUFFER_512)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	else if (max_frame <= E1000_RXBUFFER_1024)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	else if (max_frame <= E1000_RXBUFFER_2048)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	else if (max_frame <= E1000_RXBUFFER_4096)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	else if (max_frame <= E1000_RXBUFFER_8192)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	else if (max_frame <= E1000_RXBUFFER_16384)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	/* adjust allocation if LPE protects us, and we aren't using SBP */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	if (!hw->tbi_compatibility_on &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	netdev->mtu = new_mtu;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	hw->max_frame_size = max_frame;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	if (netif_running(netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		e1000_reinit_locked(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
 * e1000_update_stats - Update the board statistics counters
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
void e1000_update_stats(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	unsigned long flags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	u16 phy_tmp;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	/*
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	 * Prevent stats update while adapter is being reset, or if the pci
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	 * connection is down.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	if (adapter->link_speed == 0)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	if (pci_channel_offline(pdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	spin_lock_irqsave(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	/* these counters are modified from e1000_tbi_adjust_stats,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	 * called from the interrupt context, so they must only
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	 * be written while holding adapter->stats_lock
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	adapter->stats.crcerrs += er32(CRCERRS);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	adapter->stats.gprc += er32(GPRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	adapter->stats.gorcl += er32(GORCL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	adapter->stats.gorch += er32(GORCH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	adapter->stats.bprc += er32(BPRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	adapter->stats.mprc += er32(MPRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	adapter->stats.roc += er32(ROC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	if (hw->mac_type != e1000_ich8lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		adapter->stats.prc64 += er32(PRC64);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		adapter->stats.prc127 += er32(PRC127);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		adapter->stats.prc255 += er32(PRC255);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		adapter->stats.prc511 += er32(PRC511);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
		adapter->stats.prc1023 += er32(PRC1023);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		adapter->stats.prc1522 += er32(PRC1522);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	adapter->stats.symerrs += er32(SYMERRS);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	adapter->stats.mpc += er32(MPC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	adapter->stats.scc += er32(SCC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	adapter->stats.ecol += er32(ECOL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	adapter->stats.mcc += er32(MCC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	adapter->stats.latecol += er32(LATECOL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	adapter->stats.dc += er32(DC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	adapter->stats.sec += er32(SEC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	adapter->stats.rlec += er32(RLEC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	adapter->stats.xonrxc += er32(XONRXC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	adapter->stats.xontxc += er32(XONTXC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	adapter->stats.xoffrxc += er32(XOFFRXC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	adapter->stats.xofftxc += er32(XOFFTXC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	adapter->stats.fcruc += er32(FCRUC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
	adapter->stats.gptc += er32(GPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	adapter->stats.gotcl += er32(GOTCL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	adapter->stats.gotch += er32(GOTCH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	adapter->stats.rnbc += er32(RNBC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	adapter->stats.ruc += er32(RUC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	adapter->stats.rfc += er32(RFC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	adapter->stats.rjc += er32(RJC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	adapter->stats.torl += er32(TORL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	adapter->stats.torh += er32(TORH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	adapter->stats.totl += er32(TOTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	adapter->stats.toth += er32(TOTH);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	adapter->stats.tpr += er32(TPR);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	if (hw->mac_type != e1000_ich8lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
		adapter->stats.ptc64 += er32(PTC64);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
		adapter->stats.ptc127 += er32(PTC127);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
		adapter->stats.ptc255 += er32(PTC255);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
		adapter->stats.ptc511 += er32(PTC511);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
		adapter->stats.ptc1023 += er32(PTC1023);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
		adapter->stats.ptc1522 += er32(PTC1522);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	adapter->stats.mptc += er32(MPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	adapter->stats.bptc += er32(BPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	/* used for adaptive IFS */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	hw->tx_packet_delta = er32(TPT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	adapter->stats.tpt += hw->tx_packet_delta;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	hw->collision_delta = er32(COLC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	adapter->stats.colc += hw->collision_delta;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	if (hw->mac_type >= e1000_82543) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		adapter->stats.algnerrc += er32(ALGNERRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		adapter->stats.rxerrc += er32(RXERRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		adapter->stats.tncrs += er32(TNCRS);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		adapter->stats.cexterr += er32(CEXTERR);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		adapter->stats.tsctc += er32(TSCTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		adapter->stats.tsctfc += er32(TSCTFC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	if (hw->mac_type > e1000_82547_rev_2) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
		adapter->stats.iac += er32(IAC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
		adapter->stats.icrxoc += er32(ICRXOC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		if (hw->mac_type != e1000_ich8lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			adapter->stats.icrxptc += er32(ICRXPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
			adapter->stats.icrxatc += er32(ICRXATC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
			adapter->stats.ictxptc += er32(ICTXPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
			adapter->stats.ictxatc += er32(ICTXATC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
			adapter->stats.ictxqec += er32(ICTXQEC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
			adapter->stats.ictxqmtc += er32(ICTXQMTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
			adapter->stats.icrxdmtc += er32(ICRXDMTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	/* Fill out the OS statistics structure */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	adapter->net_stats.multicast = adapter->stats.mprc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	adapter->net_stats.collisions = adapter->stats.colc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	/* Rx Errors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	/* RLEC on some newer hardware can be incorrect so build
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	* our own version based on RUC and ROC */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		adapter->stats.crcerrs + adapter->stats.algnerrc +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		adapter->stats.ruc + adapter->stats.roc +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		adapter->stats.cexterr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	/* Tx Errors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	if (hw->bad_tx_carr_stats_fd &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	    adapter->link_duplex == FULL_DUPLEX) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		adapter->net_stats.tx_carrier_errors = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		adapter->stats.tncrs = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	/* Tx Dropped needs to be maintained elsewhere */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	/* Phy Stats */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	if (hw->media_type == e1000_media_type_copper) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
		if ((adapter->link_speed == SPEED_1000) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
			adapter->phy_stats.idle_errors += phy_tmp;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		if ((hw->mac_type <= e1000_82546) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		   (hw->phy_type == e1000_phy_m88) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
			adapter->phy_stats.receive_errors += phy_tmp;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	/* Management Stats */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	if (hw->has_smbus) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
		adapter->stats.mgptc += er32(MGTPTC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		adapter->stats.mgprc += er32(MGTPRC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
		adapter->stats.mgpdc += er32(MGTPDC);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
 * e1000_intr_msi - Interrupt Handler
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
 * @irq: interrupt number
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
 * @data: pointer to a network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
static irqreturn_t e1000_intr_msi(int irq, void *data)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	struct net_device *netdev = data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
	u32 icr = er32(ICR);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	/* in NAPI mode read ICR disables interrupts using IAM */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		hw->get_link_status = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		/* 80003ES2LAN workaround-- For packet buffer work-around on
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		 * link down event; disable receives here in the ISR and reset
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		 * adapter in watchdog */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		if (netif_carrier_ok(netdev) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		    (hw->mac_type == e1000_80003es2lan)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
			/* disable receives */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
			u32 rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		/* guard against interrupt when we're going down */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		adapter->total_tx_bytes = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		adapter->total_tx_packets = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		adapter->total_rx_bytes = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		adapter->total_rx_packets = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		__netif_rx_schedule(netdev, &adapter->napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	} else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	return IRQ_HANDLED;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
 * e1000_intr - Interrupt Handler
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
 * @irq: interrupt number
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
 * @data: pointer to a network interface device structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
static irqreturn_t e1000_intr(int irq, void *data)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	struct net_device *netdev = data;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	u32 rctl, icr = er32(ICR);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
		return IRQ_NONE;  /* Not our interrupt */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	 * not set, then the adapter didn't send an interrupt */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	if (unlikely(hw->mac_type >= e1000_82571 &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	             !(icr & E1000_ICR_INT_ASSERTED)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		return IRQ_NONE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	 * need for the IMC write */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		hw->get_link_status = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		/* 80003ES2LAN workaround--
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		 * For packet buffer work-around on link down event;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		 * disable receives here in the ISR and
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
		 * reset adapter in watchdog
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		if (netif_carrier_ok(netdev) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		    (hw->mac_type == e1000_80003es2lan)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
			/* disable receives */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
			rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
		/* guard against interrupt when we're going down */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	if (unlikely(hw->mac_type < e1000_82571)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		/* disable interrupts, without the synchronize_irq bit */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		ew32(IMC, ~0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
		E1000_WRITE_FLUSH();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		adapter->total_tx_bytes = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		adapter->total_tx_packets = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		adapter->total_rx_bytes = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		adapter->total_rx_packets = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		__netif_rx_schedule(netdev, &adapter->napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	} else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		/* this really should not happen! if it does it is basically a
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		 * bug, but not a hard error, so enable ints and continue */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
		e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	return IRQ_HANDLED;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
 * e1000_clean - NAPI Rx polling callback
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
static int e1000_clean(struct napi_struct *napi, int budget)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	struct net_device *poll_dev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	int tx_cleaned = 0, work_done = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	/* Must NOT use netdev_priv macro here. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	adapter = poll_dev->priv;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	/* e1000_clean is called per-cpu.  This lock protects
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	 * tx_ring[0] from being cleaned by multiple cpus
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	 * simultaneously.  A failure obtaining the lock means
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	 * tx_ring[0] is currently being cleaned anyway. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	if (spin_trylock(&adapter->tx_queue_lock)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		tx_cleaned = e1000_clean_tx_irq(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
						&adapter->tx_ring[0]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		spin_unlock(&adapter->tx_queue_lock);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	                  &work_done, budget);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	if (tx_cleaned)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		work_done = budget;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	/* If budget not fully consumed, exit the polling mode */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
	if (work_done < budget) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		if (likely(adapter->itr_setting & 3))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
			e1000_set_itr(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		netif_rx_complete(poll_dev, napi);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	return work_done;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
			       struct e1000_tx_ring *tx_ring)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	struct e1000_tx_desc *tx_desc, *eop_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	unsigned int i, eop;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	unsigned int count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	bool cleaned = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	unsigned int total_tx_bytes=0, total_tx_packets=0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	i = tx_ring->next_to_clean;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	eop = tx_ring->buffer_info[i].next_to_watch;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
		for (cleaned = false; !cleaned; ) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
			tx_desc = E1000_TX_DESC(*tx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
			buffer_info = &tx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
			cleaned = (i == eop);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
			if (cleaned) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
				struct sk_buff *skb = buffer_info->skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
				unsigned int segs, bytecount;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
				segs = skb_shinfo(skb)->gso_segs ?: 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
				/* multiply data chunks by size of headers */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
				bytecount = ((segs - 1) * skb_headlen(skb)) +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
				            skb->len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
				total_tx_packets += segs;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
				total_tx_bytes += bytecount;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
			tx_desc->upper.data = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
			if (unlikely(++i == tx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		eop = tx_ring->buffer_info[i].next_to_watch;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
#define E1000_TX_WEIGHT 64
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		/* weight of a sort for tx, to avoid endless transmit cleanup */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		if (count++ == E1000_TX_WEIGHT)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	tx_ring->next_to_clean = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
#define TX_WAKE_THRESHOLD 32
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		/* Make sure that anybody stopping the queue after this
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		 * sees the new next_to_clean.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
		smp_mb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
		if (netif_queue_stopped(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
			netif_wake_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			++adapter->restart_queue;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	if (adapter->detect_tx_hung) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		/* Detect a transmit hang in hardware, this serializes the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
		 * check with the clearing of time_stamp and movement of i */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		adapter->detect_tx_hung = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		if (tx_ring->buffer_info[eop].dma &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		               (adapter->tx_timeout_factor * HZ))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			/* detected Tx unit hang */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
					"  Tx Queue             <%lu>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
					"  TDH                  <%x>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
					"  TDT                  <%x>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
					"  next_to_use          <%x>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
					"  next_to_clean        <%x>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
					"buffer_info[next_to_clean]\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
					"  time_stamp           <%lx>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
					"  next_to_watch        <%x>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
					"  jiffies              <%lx>\n"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
					"  next_to_watch.status <%x>\n",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
				(unsigned long)((tx_ring - adapter->tx_ring) /
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
					sizeof(struct e1000_tx_ring)),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
				readl(hw->hw_addr + tx_ring->tdh),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
				readl(hw->hw_addr + tx_ring->tdt),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
				tx_ring->next_to_use,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
				tx_ring->next_to_clean,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
				tx_ring->buffer_info[eop].time_stamp,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
				eop,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
				jiffies,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
				eop_desc->upper.fields.status);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
			netif_stop_queue(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	adapter->total_tx_bytes += total_tx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	adapter->total_tx_packets += total_tx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	adapter->net_stats.tx_bytes += total_tx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	adapter->net_stats.tx_packets += total_tx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	return cleaned;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
 * e1000_rx_checksum - Receive Checksum Offload for 82543
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
 * @adapter:     board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
 * @status_err:  receive descriptor status and error fields
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
 * @csum:        receive descriptor csum field
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
 * @sk_buff:     socket buffer with received data
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
			      u32 csum, struct sk_buff *skb)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	u16 status = (u16)status_err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
	u8 errors = (u8)(status_err >> 24);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	skb->ip_summed = CHECKSUM_NONE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	/* 82543 or newer only */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	if (unlikely(hw->mac_type < e1000_82543)) return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
	/* Ignore Checksum bit is set */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	/* TCP/UDP checksum error bit is set */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		/* let the stack verify checksum errors */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		adapter->hw_csum_err++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	/* TCP/UDP Checksum has not been calculated */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	if (hw->mac_type <= e1000_82547_rev_2) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		if (!(status & E1000_RXD_STAT_TCPCS))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
			return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	/* It must be a TCP or UDP packet with a valid checksum */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		/* TCP checksum is good */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
		skb->ip_summed = CHECKSUM_UNNECESSARY;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
	} else if (hw->mac_type > e1000_82547_rev_2) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
		/* IP fragment with UDP payload */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
		/* Hardware complements the payload checksum, so we undo it
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		 * and then put the value in host order for further stack use.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
		__sum16 sum = (__force __sum16)htons(csum);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
		skb->csum = csum_unfold(~sum);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
		skb->ip_summed = CHECKSUM_COMPLETE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	adapter->hw_csum_good++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
			       struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
			       int *work_done, int work_to_do)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	struct e1000_rx_desc *rx_desc, *next_rxd;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	struct e1000_buffer *buffer_info, *next_buffer;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	unsigned long flags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	u32 length;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	u8 last_byte;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	int cleaned_count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	bool cleaned = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	unsigned int total_rx_bytes=0, total_rx_packets=0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	i = rx_ring->next_to_clean;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	rx_desc = E1000_RX_DESC(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	while (rx_desc->status & E1000_RXD_STAT_DD) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		struct sk_buff *skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		u8 status;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		if (*work_done >= work_to_do)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		(*work_done)++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		status = rx_desc->status;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
		skb = buffer_info->skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
		buffer_info->skb = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		prefetch(skb->data - NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		if (++i == rx_ring->count) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
		next_rxd = E1000_RX_DESC(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		prefetch(next_rxd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		next_buffer = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		cleaned = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
		cleaned_count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		pci_unmap_single(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		                 buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
		                 buffer_info->length,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
		                 PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
		length = le16_to_cpu(rx_desc->length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		/* !EOP means multiple descriptors were used to store a single
2255
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4137
		 * packet, also make sure the frame isn't just CRC only */
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4138
		if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
1900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
			/* All receives must fit into a single buffer */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
			E1000_DBG("%s: Receive packet consumed multiple"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
				  " buffers\n", netdev->name);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
			/* recycle */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
			buffer_info->skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
			goto next_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
			last_byte = *(skb->data + length - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
				       last_byte)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
				spin_lock_irqsave(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
				e1000_tbi_adjust_stats(hw, &adapter->stats,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
				                       length, skb->data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
				spin_unlock_irqrestore(&adapter->stats_lock,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
				                       flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
				length--;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
			} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
				/* recycle */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
				buffer_info->skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
				goto next_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		/* adjust length to remove Ethernet CRC, this must be
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
		 * done after the TBI_ACCEPT workaround above */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		length -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		/* probably a little skewed due to removing CRC */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		total_rx_bytes += length;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		total_rx_packets++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		/* code added for copybreak, this should improve
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		 * performance for small packets with large amounts
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		 * of reassembly being done in the stack */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		if (length < copybreak) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
			struct sk_buff *new_skb =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			if (new_skb) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
				skb_reserve(new_skb, NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
				skb_copy_to_linear_data_offset(new_skb,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
							       -NET_IP_ALIGN,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
							       (skb->data -
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
							        NET_IP_ALIGN),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
							       (length +
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
							        NET_IP_ALIGN));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
				/* save the skb in buffer_info as good */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
				buffer_info->skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
				skb = new_skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			/* else just continue with the old one */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		/* end copybreak code */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
		skb_put(skb, length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		/* Receive Checksum Offload */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		e1000_rx_checksum(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
				  (u32)(status) |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
				  ((u32)(rx_desc->errors) << 24),
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
				  le16_to_cpu(rx_desc->csum), skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		skb->protocol = eth_type_trans(skb, netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		if (unlikely(adapter->vlgrp &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
			    (status & E1000_RXD_STAT_VP))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
						 le16_to_cpu(rx_desc->special));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			netif_receive_skb(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		netdev->last_rx = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
next_desc:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
		rx_desc->status = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		/* return some buffers to hardware, one at a time is too slow */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
			cleaned_count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
		/* use prefetched values */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		rx_desc = next_rxd;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		buffer_info = next_buffer;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	rx_ring->next_to_clean = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	if (cleaned_count)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	adapter->total_rx_packets += total_rx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	adapter->total_rx_bytes += total_rx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	adapter->net_stats.rx_bytes += total_rx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	adapter->net_stats.rx_packets += total_rx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	return cleaned;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * @adapter: board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
				  struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
				  int *work_done, int work_to_do)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	struct e1000_buffer *buffer_info, *next_buffer;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	struct e1000_ps_page *ps_page;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
	struct e1000_ps_page_dma *ps_page_dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	struct sk_buff *skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	unsigned int i, j;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	u32 length, staterr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	int cleaned_count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	bool cleaned = false;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	unsigned int total_rx_bytes=0, total_rx_packets=0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	i = rx_ring->next_to_clean;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	while (staterr & E1000_RXD_STAT_DD) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
		ps_page = &rx_ring->ps_page[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		ps_page_dma = &rx_ring->ps_page_dma[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
		if (unlikely(*work_done >= work_to_do))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
		(*work_done)++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
		skb = buffer_info->skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		/* in the packet split case this is header only */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		prefetch(skb->data - NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		if (++i == rx_ring->count) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		prefetch(next_rxd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		next_buffer = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		cleaned = true;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		cleaned_count++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		pci_unmap_single(pdev, buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
				 buffer_info->length,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
				 PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
			E1000_DBG("%s: Packet Split buffers didn't pick up"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
				  " the full packet\n", netdev->name);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
			dev_kfree_skb_irq(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
			goto next_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			dev_kfree_skb_irq(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
			goto next_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
		length = le16_to_cpu(rx_desc->wb.middle.length0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
		if (unlikely(!length)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
			E1000_DBG("%s: Last part of the packet spanning"
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
				  " multiple descriptors\n", netdev->name);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
			dev_kfree_skb_irq(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
			goto next_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		/* Good Receive */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		skb_put(skb, length);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		/* this looks ugly, but it seems compiler issues make it
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		   more efficient than reusing j */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		/* page alloc/put takes too long and effects small packet
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
		 * throughput, so unsplit small packets and save the alloc/put*/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			u8 *vaddr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
			/* there is no documentation about how to call
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
			 * kmap_atomic, so we can't hold the mapping
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
			 * very long */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			pci_dma_sync_single_for_cpu(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
				ps_page_dma->ps_page_dma[0],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
				PAGE_SIZE,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
				PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			vaddr = kmap_atomic(ps_page->ps_page[0],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
			                    KM_SKB_DATA_SOFTIRQ);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
			memcpy(skb_tail_pointer(skb), vaddr, l1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
			pci_dma_sync_single_for_device(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
				ps_page_dma->ps_page_dma[0],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			/* remove the CRC */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
			l1 -= 4;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			skb_put(skb, l1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
			goto copydone;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		} /* if */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		for (j = 0; j < adapter->rx_ps_pages; j++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
			if (!length)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
			pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
					PAGE_SIZE, PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
			ps_page_dma->ps_page_dma[j] = 0;
2255
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4352
			skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4353
			                   length);
1900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
			ps_page->ps_page[j] = NULL;
2255
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4355
			skb->len += length;
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4356
			skb->data_len += length;
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4357
			skb->truesize += length;
1900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		/* strip the ethernet crc, problem is we're using pages now so
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		 * this whole operation can get a little cpu intensive */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
		pskb_trim(skb, skb->len - 4);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
copydone:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		total_rx_bytes += skb->len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		total_rx_packets++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		e1000_rx_checksum(adapter, staterr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
				  le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		skb->protocol = eth_type_trans(skb, netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		if (likely(rx_desc->wb.upper.header_status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
			adapter->rx_hdr_split++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
		if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
				le16_to_cpu(rx_desc->wb.middle.vlan));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
			netif_receive_skb(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		netdev->last_rx = jiffies;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
next_desc:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		buffer_info->skb = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		/* return some buffers to hardware, one at a time is too slow */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			cleaned_count = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
		/* use prefetched values */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
		rx_desc = next_rxd;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		buffer_info = next_buffer;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	rx_ring->next_to_clean = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	if (cleaned_count)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	adapter->total_rx_packets += total_rx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	adapter->total_rx_bytes += total_rx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	adapter->net_stats.rx_bytes += total_rx_bytes;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	adapter->net_stats.rx_packets += total_rx_packets;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	return cleaned;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
				   struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
				   int cleaned_count)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	struct e1000_rx_desc *rx_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	struct sk_buff *skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	unsigned int i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
	i = rx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	while (cleaned_count--) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		skb = buffer_info->skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
		if (skb) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
			skb_trim(skb, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
			goto map_skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		skb = netdev_alloc_skb(netdev, bufsz);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
		if (unlikely(!skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
			/* Better luck next round */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
			adapter->alloc_rx_buff_failed++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
		/* Fix for errata 23, can't cross 64kB boundary */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
			struct sk_buff *oldskb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
					     "at %p\n", bufsz, skb->data);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
			/* Try again, without freeing the previous */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
			skb = netdev_alloc_skb(netdev, bufsz);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
			/* Failed allocation, critical failure */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
			if (!skb) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
				dev_kfree_skb(oldskb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
				/* give up */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
				dev_kfree_skb(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
				dev_kfree_skb(oldskb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
				break; /* while !buffer_info->skb */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
			/* Use new allocation */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			dev_kfree_skb(oldskb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		/* Make buffer alignment 2 beyond a 16 byte boundary
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		 * this will result in a 16 byte aligned IP header after
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		 * the 14 byte MAC header is removed
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		skb_reserve(skb, NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		buffer_info->skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
		buffer_info->length = adapter->rx_buffer_len;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
map_skb:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		buffer_info->dma = pci_map_single(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
						  skb->data,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
						  adapter->rx_buffer_len,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
						  PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		/* Fix for errata 23, can't cross 64kB boundary */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
		if (!e1000_check_64k_bound(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
					(void *)(unsigned long)buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
					adapter->rx_buffer_len)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
			DPRINTK(RX_ERR, ERR,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
				"dma align check failed: %u bytes at %p\n",
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
				adapter->rx_buffer_len,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
				(void *)(unsigned long)buffer_info->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
			dev_kfree_skb(skb);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
			buffer_info->skb = NULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
			pci_unmap_single(pdev, buffer_info->dma,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
					 adapter->rx_buffer_len,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
					 PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			break; /* while !buffer_info->skb */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
		rx_desc = E1000_RX_DESC(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		if (unlikely(++i == rx_ring->count))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
			i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	if (likely(rx_ring->next_to_use != i)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		rx_ring->next_to_use = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		if (unlikely(i-- == 0))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			i = (rx_ring->count - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		/* Force memory writes to complete before letting h/w
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		 * know there are new descriptors to fetch.  (Only
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		 * applicable for weak-ordered memory model archs,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		 * such as IA-64). */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		wmb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		writel(i, hw->hw_addr + rx_ring->rdt);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
 * @adapter: address of board private structure
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
				      struct e1000_rx_ring *rx_ring,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
				      int cleaned_count)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	struct net_device *netdev = adapter->netdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	struct pci_dev *pdev = adapter->pdev;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	union e1000_rx_desc_packet_split *rx_desc;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	struct e1000_buffer *buffer_info;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	struct e1000_ps_page *ps_page;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	struct e1000_ps_page_dma *ps_page_dma;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	struct sk_buff *skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	unsigned int i, j;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	i = rx_ring->next_to_use;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	ps_page = &rx_ring->ps_page[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	ps_page_dma = &rx_ring->ps_page_dma[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	while (cleaned_count--) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
			if (j < adapter->rx_ps_pages) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
				if (likely(!ps_page->ps_page[j])) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
					ps_page->ps_page[j] =
2255
25b351a76050 Added changes in e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents: 1900
diff changeset
  4556
						alloc_page(GFP_ATOMIC);
1900
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
					if (unlikely(!ps_page->ps_page[j])) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
						adapter->alloc_rx_buff_failed++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
						goto no_buffers;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
					}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
					ps_page_dma->ps_page_dma[j] =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
						pci_map_page(pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
							    ps_page->ps_page[j],
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
							    0, PAGE_SIZE,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
							    PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
				/* Refresh the desc even if buffer_addrs didn't
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
				 * change because each write-back erases
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
				 * this info.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
				 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
				rx_desc->read.buffer_addr[j+1] =
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
				     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			} else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
				rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		skb = netdev_alloc_skb(netdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
		                       adapter->rx_ps_bsize0 + NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		if (unlikely(!skb)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			adapter->alloc_rx_buff_failed++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
			break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		/* Make buffer alignment 2 beyond a 16 byte boundary
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
		 * this will result in a 16 byte aligned IP header after
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		 * the 14 byte MAC header is removed
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		skb_reserve(skb, NET_IP_ALIGN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
		buffer_info->skb = skb;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		buffer_info->length = adapter->rx_ps_bsize0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		buffer_info->dma = pci_map_single(pdev, skb->data,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
						  adapter->rx_ps_bsize0,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
						  PCI_DMA_FROMDEVICE);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		if (unlikely(++i == rx_ring->count)) i = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		buffer_info = &rx_ring->buffer_info[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		ps_page = &rx_ring->ps_page[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		ps_page_dma = &rx_ring->ps_page_dma[i];
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
no_buffers:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	if (likely(rx_ring->next_to_use != i)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		rx_ring->next_to_use = i;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
		if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		/* Force memory writes to complete before letting h/w
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		 * know there are new descriptors to fetch.  (Only
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
		 * applicable for weak-ordered memory model archs,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
		 * such as IA-64). */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
		wmb();
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		/* Hardware increments by 16 bytes, but packet split
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
		 * descriptors are 32 bytes...so we increment tail
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
		 * twice as much.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
		 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
		writel(i<<1, hw->hw_addr + rx_ring->rdt);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
 * @adapter:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
static void e1000_smartspeed(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	u16 phy_status;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
	u16 phy_ctrl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
	if (adapter->smartspeed == 0) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		/* If Master/Slave config fault is asserted twice,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		 * we assume back-to-back */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
					    phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
			adapter->smartspeed++;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
			if (!e1000_phy_setup_autoneg(hw) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
			   !e1000_read_phy_reg(hw, PHY_CTRL,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
				   	       &phy_ctrl)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
					     MII_CR_RESTART_AUTO_NEG);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
				e1000_write_phy_reg(hw, PHY_CTRL,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
						    phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
		/* If still no link, perhaps using 2/3 pair cable */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
		phy_ctrl |= CR_1000T_MS_ENABLE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		if (!e1000_phy_setup_autoneg(hw) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
				     MII_CR_RESTART_AUTO_NEG);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		adapter->smartspeed = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
 * e1000_ioctl -
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
 * @netdev:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
 * @ifreq:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
 * @cmd:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	switch (cmd) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
	case SIOCGMIIPHY:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	case SIOCGMIIREG:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	case SIOCSMIIREG:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		return e1000_mii_ioctl(netdev, ifr, cmd);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		return -EOPNOTSUPP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
 * e1000_mii_ioctl -
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
 * @netdev:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
 * @ifreq:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
 * @cmd:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
 **/
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
			   int cmd)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	struct mii_ioctl_data *data = if_mii(ifr);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	int retval;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	u16 mii_reg;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	u16 spddplx;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	unsigned long flags;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	if (hw->media_type != e1000_media_type_copper)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		return -EOPNOTSUPP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	switch (cmd) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	case SIOCGMIIPHY:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		data->phy_id = hw->phy_addr;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	case SIOCGMIIREG:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		if (!capable(CAP_NET_ADMIN))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
			return -EPERM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		spin_lock_irqsave(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
				   &data->val_out)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
			return -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	case SIOCSMIIREG:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		if (!capable(CAP_NET_ADMIN))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
			return -EPERM;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		if (data->reg_num & ~(0x1F))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
			return -EFAULT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		mii_reg = data->val_in;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
		spin_lock_irqsave(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
		if (e1000_write_phy_reg(hw, data->reg_num,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
					mii_reg)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
			return -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		if (hw->media_type == e1000_media_type_copper) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
			switch (data->reg_num) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
			case PHY_CTRL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
				if (mii_reg & MII_CR_POWER_DOWN)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
					hw->autoneg = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
					hw->autoneg_advertised = 0x2F;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
				} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
					if (mii_reg & 0x40)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
						spddplx = SPEED_1000;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
					else if (mii_reg & 0x2000)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
						spddplx = SPEED_100;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
					else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
						spddplx = SPEED_10;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
					spddplx += (mii_reg & 0x100)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
						   ? DUPLEX_FULL :
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
						   DUPLEX_HALF;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
					retval = e1000_set_spd_dplx(adapter,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
								    spddplx);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
					if (retval)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
						return retval;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
				}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
				if (netif_running(adapter->netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
					e1000_reinit_locked(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
				else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
					e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
			case M88E1000_PHY_SPEC_CTRL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
			case M88E1000_EXT_PHY_SPEC_CTRL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
				if (e1000_phy_reset(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
					return -EIO;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
		} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
			switch (data->reg_num) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
			case PHY_CTRL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
				if (mii_reg & MII_CR_POWER_DOWN)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
					break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
				if (netif_running(adapter->netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
					e1000_reinit_locked(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
				else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
					e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
				break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
		return -EOPNOTSUPP;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	return E1000_SUCCESS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
void e1000_pci_set_mwi(struct e1000_hw *hw)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	struct e1000_adapter *adapter = hw->back;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	int ret_val = pci_set_mwi(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	if (ret_val)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
void e1000_pci_clear_mwi(struct e1000_hw *hw)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	struct e1000_adapter *adapter = hw->back;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	pci_clear_mwi(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
	struct e1000_adapter *adapter = hw->back;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	return pcix_get_mmrbc(adapter->pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	struct e1000_adapter *adapter = hw->back;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
	pcix_set_mmrbc(adapter->pdev, mmrbc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
    struct e1000_adapter *adapter = hw->back;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
    u16 cap_offset;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
    if (!cap_offset)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
        return -E1000_ERR_CONFIG;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
    return E1000_SUCCESS;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	outl(value, port);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
static void e1000_vlan_rx_register(struct net_device *netdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
				   struct vlan_group *grp)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	u32 ctrl, rctl;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		e1000_irq_disable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	adapter->vlgrp = grp;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
	if (grp) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		/* enable VLAN tag insert/strip */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		ctrl = er32(CTRL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
		ctrl |= E1000_CTRL_VME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		ew32(CTRL, ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
		if (adapter->hw.mac_type != e1000_ich8lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			/* enable VLAN receive filtering */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
			rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
			rctl &= ~E1000_RCTL_CFIEN;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
			ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			e1000_update_mng_vlan(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
		/* disable VLAN tag insert/strip */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
		ctrl = er32(CTRL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
		ctrl &= ~E1000_CTRL_VME;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
		ew32(CTRL, ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
		if (adapter->hw.mac_type != e1000_ich8lan) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			if (adapter->mng_vlan_id !=
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
			    (u16)E1000_MNG_VLAN_NONE) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
				e1000_vlan_rx_kill_vid(netdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
				                       adapter->mng_vlan_id);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
			}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
	if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
		e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
	u32 vfta, index;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	if ((hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	    (vid == adapter->mng_vlan_id))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
	/* add VID to filter table */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
	index = (vid >> 5) & 0x7F;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	vfta |= (1 << (vid & 0x1F));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	e1000_write_vfta(hw, index, vfta);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
	u32 vfta, index;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
		e1000_irq_disable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	if (!test_bit(__E1000_DOWN, &adapter->flags))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
		e1000_irq_enable(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	if ((hw->mng_cookie.status &
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	    (vid == adapter->mng_vlan_id)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
		/* release control to f/w */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
		e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	/* remove VID from filter table */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	index = (vid >> 5) & 0x7F;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	vfta &= ~(1 << (vid & 0x1F));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	e1000_write_vfta(hw, index, vfta);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
static void e1000_restore_vlan(struct e1000_adapter *adapter)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	if (adapter->vlgrp) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		u16 vid;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
			if (!vlan_group_get_device(adapter->vlgrp, vid))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
				continue;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
	hw->autoneg = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	/* Fiber NICs only allow 1000 gbps Full duplex */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	if ((hw->media_type == e1000_media_type_fiber) &&
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
		return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	switch (spddplx) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
	case SPEED_10 + DUPLEX_HALF:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
		hw->forced_speed_duplex = e1000_10_half;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	case SPEED_10 + DUPLEX_FULL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
		hw->forced_speed_duplex = e1000_10_full;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	case SPEED_100 + DUPLEX_HALF:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
		hw->forced_speed_duplex = e1000_100_half;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	case SPEED_100 + DUPLEX_FULL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
		hw->forced_speed_duplex = e1000_100_full;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
	case SPEED_1000 + DUPLEX_FULL:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		hw->autoneg = 1;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		break;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	default:
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		return -EINVAL;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
	u32 ctrl, ctrl_ext, rctl, status;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
	u32 wufc = adapter->wol;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
#ifdef CONFIG_PM
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
	int retval = 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	netif_device_detach(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	if (netif_running(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
		e1000_down(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
#ifdef CONFIG_PM
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	retval = pci_save_state(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	if (retval)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
		return retval;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	status = er32(STATUS);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	if (status & E1000_STATUS_LU)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
		wufc &= ~E1000_WUFC_LNKC;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
	if (wufc) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
		e1000_setup_rctl(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
		e1000_set_rx_mode(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
		/* turn on all-multi mode if wake on multicast is enabled */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
		if (wufc & E1000_WUFC_MC) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
			rctl = er32(RCTL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
			rctl |= E1000_RCTL_MPE;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
			ew32(RCTL, rctl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
		if (hw->mac_type >= e1000_82540) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
			ctrl = er32(CTRL);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
			/* advertise wake from D3Cold */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
			#define E1000_CTRL_ADVD3WUC 0x00100000
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
			/* phy power management enable */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
			ctrl |= E1000_CTRL_ADVD3WUC |
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
				E1000_CTRL_EN_PHY_PWR_MGMT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
			ew32(CTRL, ctrl);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
		if (hw->media_type == e1000_media_type_fiber ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		   hw->media_type == e1000_media_type_internal_serdes) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
			/* keep the laser running in D3 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
			ctrl_ext = er32(CTRL_EXT);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
			ew32(CTRL_EXT, ctrl_ext);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
		/* Allow time for pending master requests to run */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		e1000_disable_pciex_master(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
		ew32(WUC, E1000_WUC_PME_EN);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
		ew32(WUFC, wufc);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		pci_enable_wake(pdev, PCI_D3hot, 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		pci_enable_wake(pdev, PCI_D3cold, 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
	} else {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
		ew32(WUC, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		ew32(WUFC, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
		pci_enable_wake(pdev, PCI_D3hot, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
		pci_enable_wake(pdev, PCI_D3cold, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
	e1000_release_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
	/* make sure adapter isn't asleep if manageability is enabled */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
	if (adapter->en_mng_pt) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
		pci_enable_wake(pdev, PCI_D3hot, 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
		pci_enable_wake(pdev, PCI_D3cold, 1);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
	if (hw->phy_type == e1000_phy_igp_3)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
		e1000_phy_powerdown_workaround(hw);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
	if (netif_running(netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		e1000_free_irq(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	 * would have already happened in close and is redundant. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	e1000_release_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	pci_disable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
#ifdef CONFIG_PM
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
static int e1000_resume(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	u32 err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	pci_set_power_state(pdev, PCI_D0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	pci_restore_state(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	if (adapter->need_ioport)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		err = pci_enable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
		err = pci_enable_device_mem(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
	pci_set_master(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	pci_enable_wake(pdev, PCI_D3hot, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	pci_enable_wake(pdev, PCI_D3cold, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	if (netif_running(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
		err = e1000_request_irq(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
		if (err)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
			return err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	e1000_power_up_phy(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	ew32(WUS, ~0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	e1000_init_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	if (netif_running(netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
		e1000_up(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	netif_device_attach(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
	/* If the controller is 82573 and f/w is AMT, do not set
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	 * DRV_LOAD until the interface is up.  For all other cases,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
	 * let the f/w know that the h/w is now under the control
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	 * of the driver. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	if (hw->mac_type != e1000_82573 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
	    !e1000_check_mng_mode(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
		e1000_get_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
	return 0;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
static void e1000_shutdown(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	e1000_suspend(pdev, PMSG_SUSPEND);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
#ifdef CONFIG_NET_POLL_CONTROLLER
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
/*
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
 * Polling 'interrupt' - used by things like netconsole to send skbs
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
 * without having to re-enable interrupts. It's not called while
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
 * the interrupt routine is executing.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
static void e1000_netpoll(struct net_device *netdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
	struct e1000_adapter *adapter = netdev_priv(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
	disable_irq(adapter->pdev->irq);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	e1000_intr(adapter->pdev->irq, netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	enable_irq(adapter->pdev->irq);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
#endif
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
 * e1000_io_error_detected - called when PCI error is detected
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
 * @pdev: Pointer to PCI device
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
 * @state: The current pci conneection state
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
 * This function is called after a PCI bus error affecting
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
 * this device has been detected.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
						pci_channel_state_t state)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	struct e1000_adapter *adapter = netdev->priv;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	netif_device_detach(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	if (netif_running(netdev))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
		e1000_down(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	pci_disable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
	/* Request a slot slot reset. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	return PCI_ERS_RESULT_NEED_RESET;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
 * e1000_io_slot_reset - called after the pci bus has been reset.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
 * @pdev: Pointer to PCI device
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
 * Restart the card from scratch, as if from a cold-boot. Implementation
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
 * resembles the first-half of the e1000_resume routine.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
	struct e1000_adapter *adapter = netdev->priv;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	int err;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
	if (adapter->need_ioport)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		err = pci_enable_device(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	else
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
		err = pci_enable_device_mem(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
	if (err) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
		return PCI_ERS_RESULT_DISCONNECT;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	pci_set_master(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	pci_enable_wake(pdev, PCI_D3hot, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	pci_enable_wake(pdev, PCI_D3cold, 0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	e1000_reset(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	ew32(WUS, ~0);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	return PCI_ERS_RESULT_RECOVERED;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
/**
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
 * e1000_io_resume - called when traffic can start flowing again.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
 * @pdev: Pointer to PCI device
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
 *
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
 * This callback is called when the error recovery driver tells us that
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
 * its OK to resume normal operation. Implementation resembles the
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
 * second-half of the e1000_resume routine.
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
 */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
static void e1000_io_resume(struct pci_dev *pdev)
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
{
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	struct net_device *netdev = pci_get_drvdata(pdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
	struct e1000_adapter *adapter = netdev->priv;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
	struct e1000_hw *hw = &adapter->hw;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
	e1000_init_manageability(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
	if (netif_running(netdev)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		if (e1000_up(adapter)) {
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
			printk("e1000: can't bring device back up after reset\n");
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
			return;
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
		}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
	netif_device_attach(netdev);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
	/* If the controller is 82573 and f/w is AMT, do not set
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
	 * DRV_LOAD until the interface is up.  For all other cases,
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	 * let the f/w know that the h/w is now under the control
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	 * of the driver. */
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	if (hw->mac_type != e1000_82573 ||
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	    !e1000_check_mng_mode(hw))
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
		e1000_get_hw_control(adapter);
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
}
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
25f848e2fbf4 Added e1000 driver for 2.6.27.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
/* e1000_main.c */