devices/e1000/e1000_main-2.6.37-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 13:12:24 -0400
changeset 2629 a2701af27fde
parent 2173 312ab8ed8284
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.
2173
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k8-NAPI"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_update_phy_info_task(struct work_struct *work);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_watchdog(unsigned long data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static void e1000_82547_tx_fifo_stall(unsigned long data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
				    struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static int e1000_set_mac(struct net_device *netdev, void *p);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static irqreturn_t e1000_intr(int irq, void *data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
			       struct e1000_tx_ring *tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static int e1000_clean(struct napi_struct *napi, int budget);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
			       struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
			       int *work_done, int work_to_do);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
				     struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
				     int *work_done, int work_to_do);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
				   struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
				   int cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
					 struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
					 int cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
			   int cmd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_tx_timeout(struct net_device *dev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static void e1000_reset_task(struct work_struct *work);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static void e1000_smartspeed(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
                                       struct sk_buff *skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static void e1000_restore_vlan(struct e1000_adapter *adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
#ifdef CONFIG_PM
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static int e1000_resume(struct pci_dev *pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static void e1000_shutdown(struct pci_dev *pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
#ifdef CONFIG_NET_POLL_CONTROLLER
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
/* for netdump / net console */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static void e1000_netpoll (struct net_device *netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
#define COPYBREAK_DEFAULT 256
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
module_param(copybreak, uint, 0644);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
MODULE_PARM_DESC(copybreak,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	"Maximum size of packet that is copied to a new buffer on receive");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
                     pci_channel_state_t state);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static void e1000_io_resume(struct pci_dev *pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
static struct pci_error_handlers e1000_err_handler = {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.error_detected = e1000_io_error_detected,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	.slot_reset = e1000_io_slot_reset,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	.resume = e1000_io_resume,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
};
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
static struct pci_driver e1000_driver = {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.name     = e1000_driver_name,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.id_table = e1000_pci_tbl,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	.probe    = e1000_probe,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	.remove   = __devexit_p(e1000_remove),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
#ifdef CONFIG_PM
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	/* Power Managment Hooks */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	.suspend  = e1000_suspend,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.resume   = e1000_resume,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	.shutdown = e1000_shutdown,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	.err_handler = &e1000_err_handler
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
};
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
MODULE_LICENSE("GPL");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
MODULE_VERSION(DRV_VERSION);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
module_param(debug, int, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 * e1000_get_hw_dev - return device
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 * used by hardware layer to print debugging information
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	struct e1000_adapter *adapter = hw->back;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	return adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
 * e1000_init_module - Driver Registration Routine
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 * e1000_init_module is the first routine called when the driver is
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
 * loaded. All it does is register with the PCI subsystem.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
static int __init e1000_init_module(void)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	int ret;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	pr_info("%s\n", e1000_copyright);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	ret = pci_register_driver(&e1000_driver);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	if (copybreak != COPYBREAK_DEFAULT) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
		if (copybreak == 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
			pr_info("copybreak disabled\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
		else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
			pr_info("copybreak enabled for "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
				   "packets <= %u bytes\n", copybreak);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	return ret;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
module_init(e1000_init_module);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 * e1000_exit_module - Driver Exit Cleanup Routine
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 * e1000_exit_module is called just before the driver is removed
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
 * from memory.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
static void __exit e1000_exit_module(void)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	pci_unregister_driver(&e1000_driver);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
module_exit(e1000_exit_module);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
static int e1000_request_irq(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	irq_handler_t handler = e1000_intr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	int irq_flags = IRQF_SHARED;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	int err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	                  netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
static void e1000_free_irq(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	free_irq(adapter->pdev->irq, netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
 * e1000_irq_disable - Mask off interrupt generation on the NIC
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
static void e1000_irq_disable(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	ew32(IMC, ~0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	synchronize_irq(adapter->pdev->irq);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
 * e1000_irq_enable - Enable default interrupt generation settings
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
static void e1000_irq_enable(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	ew32(IMS, IMS_ENABLE_MASK);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	u16 vid = hw->mng_cookie.vlan_id;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	u16 old_vid = adapter->mng_vlan_id;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	if (adapter->vlgrp) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
			if (hw->mng_cookie.status &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
				e1000_vlan_rx_add_vid(netdev, vid);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
				adapter->mng_vlan_id = vid;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
			} else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
					(vid != old_vid) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
				e1000_vlan_rx_kill_vid(netdev, old_vid);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		} else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
			adapter->mng_vlan_id = vid;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
static void e1000_init_manageability(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	if (adapter->en_mng_pt) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		u32 manc = er32(MANC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
		/* disable hardware interception of ARP */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		manc &= ~(E1000_MANC_ARP_EN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		ew32(MANC, manc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
static void e1000_release_manageability(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
	if (adapter->en_mng_pt) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		u32 manc = er32(MANC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
		/* re-enable hardware interception of ARP */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		manc |= E1000_MANC_ARP_EN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		ew32(MANC, manc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
 * e1000_configure - configure the hardware for RX and TX
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
 * @adapter = private board structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
static void e1000_configure(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	e1000_set_rx_mode(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	e1000_restore_vlan(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	e1000_init_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	e1000_configure_tx(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	e1000_setup_rctl(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	e1000_configure_rx(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	/* call E1000_DESC_UNUSED which always leaves
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	 * at least 1 descriptor unused to make sure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	 * next_to_use != next_to_clean */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	for (i = 0; i < adapter->num_rx_queues; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		adapter->alloc_rx_buf(adapter, ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		                      E1000_DESC_UNUSED(ring));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
int e1000_up(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	/* hardware has been reset, we need to reload some things */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	e1000_configure(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	clear_bit(__E1000_DOWN, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	napi_enable(&adapter->napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	netif_wake_queue(adapter->netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	/* fire a link change interrupt to start the watchdog */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	ew32(ICS, E1000_ICS_LSC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
 * e1000_power_up_phy - restore link in case the phy was powered down
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 * @adapter: address of board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 * The phy may be powered down to save power and turn off link when the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 * driver is unloaded and wake on lan is not enabled (among others)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 * *** this routine MUST be followed by a call to e1000_reset ***
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
void e1000_power_up_phy(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	u16 mii_reg = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	/* Just clear the power down bit to wake the phy back up */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
	if (hw->media_type == e1000_media_type_copper) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		/* according to the manual, the phy will retain its
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		 * settings across a power-down/up cycle */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
		mii_reg &= ~MII_CR_POWER_DOWN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
static void e1000_power_down_phy(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	/* Power down the PHY so no link is implied when interface is down *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	 * The PHY cannot be powered down if any of the following is true *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	 * (a) WoL is enabled
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	 * (b) AMT is active
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	 * (c) SoL/IDER session is active */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	   hw->media_type == e1000_media_type_copper) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		u16 mii_reg = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		case e1000_82540:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		case e1000_82545:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		case e1000_82545_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		case e1000_82546:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		case e1000_82546_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		case e1000_82541:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		case e1000_82541_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		case e1000_82547:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		case e1000_82547_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
				goto out;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
			goto out;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		mii_reg |= MII_CR_POWER_DOWN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		mdelay(1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
out:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
void e1000_down(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	u32 rctl, tctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	/* disable receives in the hardware */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	/* flush and sleep below */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	netif_tx_disable(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	/* disable transmits in the hardware */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	tctl = er32(TCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	tctl &= ~E1000_TCTL_EN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	ew32(TCTL, tctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	/* flush both disables and wait for them to finish */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	msleep(10);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	napi_disable(&adapter->napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	e1000_irq_disable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	 * Setting DOWN must be after irq_disable to prevent
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	 * a screaming interrupt.  Setting DOWN also prevents
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	 * timers and tasks from rescheduling.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	set_bit(__E1000_DOWN, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	del_timer_sync(&adapter->tx_fifo_stall_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	del_timer_sync(&adapter->watchdog_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	del_timer_sync(&adapter->phy_info_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	adapter->link_speed = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	adapter->link_duplex = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	netif_carrier_off(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	e1000_clean_all_tx_rings(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	e1000_clean_all_rx_rings(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
static void e1000_reinit_safe(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		msleep(1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	rtnl_lock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	e1000_up(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	rtnl_unlock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	clear_bit(__E1000_RESETTING, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
void e1000_reinit_locked(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	/* if rtnl_lock is not held the call path is bogus */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	ASSERT_RTNL();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	WARN_ON(in_interrupt());
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		msleep(1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	e1000_up(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	clear_bit(__E1000_RESETTING, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
void e1000_reset(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	bool legacy_pba_adjust = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	u16 hwm;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	/* Repartition Pba for greater than 9k mtu
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	 * To take effect CTRL.RST is required.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	case e1000_82542_rev2_0:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	case e1000_82542_rev2_1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	case e1000_82543:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	case e1000_82544:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	case e1000_82540:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	case e1000_82541:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	case e1000_82541_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		legacy_pba_adjust = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		pba = E1000_PBA_48K;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	case e1000_82545:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	case e1000_82545_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	case e1000_82546:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	case e1000_82546_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		pba = E1000_PBA_48K;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	case e1000_82547:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	case e1000_82547_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		legacy_pba_adjust = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		pba = E1000_PBA_30K;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	case e1000_undefined:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	case e1000_num_macs:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	if (legacy_pba_adjust) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
			pba -= 8; /* allocate more FIFO for Tx */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		if (hw->mac_type == e1000_82547) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
			adapter->tx_fifo_head = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
			adapter->tx_fifo_size =
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
			atomic_set(&adapter->tx_fifo_stall, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		/* adjust PBA for jumbo frames */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		ew32(PBA, pba);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		/* To maintain wire speed transmits, the Tx FIFO should be
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		 * large enough to accommodate two full transmit packets,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		 * the Rx FIFO should be large enough to accommodate at least
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		 * one full receive packet and is similarly rounded up and
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		 * expressed in KB. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		pba = er32(PBA);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		/* upper 16 bits has Tx packet buffer allocation size in KB */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		tx_space = pba >> 16;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		/* lower 16 bits has Rx packet buffer allocation size in KB */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		pba &= 0xffff;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		 * the tx fifo also stores 16 bytes of information about the tx
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
		 * but don't include ethernet FCS because hardware appends it
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		min_tx_space = (hw->max_frame_size +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		                sizeof(struct e1000_tx_desc) -
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		                ETH_FCS_LEN) * 2;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		min_tx_space = ALIGN(min_tx_space, 1024);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		min_tx_space >>= 10;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		/* software strips receive CRC, so leave room for it */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		min_rx_space = hw->max_frame_size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		min_rx_space = ALIGN(min_rx_space, 1024);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		min_rx_space >>= 10;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		/* If current Tx allocation is less than the min Tx FIFO size,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		 * and the min Tx FIFO size is less than the current Rx FIFO
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		 * allocation, take space away from current Rx allocation */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		if (tx_space < min_tx_space &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		    ((min_tx_space - tx_space) < pba)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
			pba = pba - (min_tx_space - tx_space);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
			/* PCI/PCIx hardware has PBA alignment constraints */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
			switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
			case e1000_82545 ... e1000_82546_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
				pba &= ~(E1000_PBA_8K - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
			default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
			/* if short on rx space, rx wins and must trump tx
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
			 * adjustment or use Early Receive if available */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
			if (pba < min_rx_space)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
				pba = min_rx_space;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	ew32(PBA, pba);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	 * flow control settings:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	 * The high water mark must be low enough to fit one full frame
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	 * (or the size used for early receive) above it in the Rx FIFO.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	 * Set it to the lower of:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	 * - 90% of the Rx FIFO size, and
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	 * - the full Rx FIFO size minus the early receive size (for parts
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	 * - the full Rx FIFO size minus one full frame
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	hwm = min(((pba << 10) * 9 / 10),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		  ((pba << 10) - hw->max_frame_size));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	hw->fc_low_water = hw->fc_high_water - 8;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	hw->fc_send_xon = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	hw->fc = hw->original_fc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	/* Allow time for pending master requests to run */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	e1000_reset_hw(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	if (hw->mac_type >= e1000_82544)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		ew32(WUC, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	if (e1000_init_hw(hw))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		e_dev_err("Hardware Error\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	e1000_update_mng_vlan(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	if (hw->mac_type >= e1000_82544 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	    hw->autoneg == 1 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		u32 ctrl = er32(CTRL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		/* clear phy power management bit if we are in gig only mode,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		 * which if enabled will attempt negotiation to 100Mb, which
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		 * can cause a loss of link at power off or driver unload */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		ctrl &= ~E1000_CTRL_SWDPIN3;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		ew32(CTRL, ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	e1000_reset_adaptive(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	e1000_phy_get_info(hw, &adapter->phy_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	e1000_release_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 *  Dump the eeprom for users having checksum issues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	struct ethtool_eeprom eeprom;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	const struct ethtool_ops *ops = netdev->ethtool_ops;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	u8 *data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	u16 csum_old, csum_new = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	eeprom.len = ops->get_eeprom_len(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	eeprom.offset = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	data = kmalloc(eeprom.len, GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	if (!data) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
		pr_err("Unable to allocate memory to dump EEPROM data\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	ops->get_eeprom(netdev, &eeprom, data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
		csum_new += data[i] + (data[i + 1] << 8);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	csum_new = EEPROM_SUM - csum_new;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	pr_err("/*********************/\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	pr_err("Calculated              : 0x%04x\n", csum_new);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	pr_err("Offset    Values\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	pr_err("========  ======\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	pr_err("Include this output when contacting your support provider.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	pr_err("This is not a software error! Something bad happened to\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	pr_err("result in further problems, possibly loss of data,\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	pr_err("corruption or system hangs!\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	pr_err("which is invalid and requires you to set the proper MAC\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	pr_err("address manually before continuing to enable this network\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	pr_err("device. Please inspect the EEPROM dump and report the\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	pr_err("/*********************/\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	kfree(data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
 * @pdev: PCI device information struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
 * Return true if an adapter needs ioport resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
static int e1000_is_need_ioport(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	switch (pdev->device) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	case E1000_DEV_ID_82540EM:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case E1000_DEV_ID_82540EM_LOM:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	case E1000_DEV_ID_82540EP:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	case E1000_DEV_ID_82540EP_LOM:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	case E1000_DEV_ID_82540EP_LP:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	case E1000_DEV_ID_82541EI:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	case E1000_DEV_ID_82541EI_MOBILE:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	case E1000_DEV_ID_82541ER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	case E1000_DEV_ID_82541ER_LOM:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	case E1000_DEV_ID_82541GI:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	case E1000_DEV_ID_82541GI_LF:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	case E1000_DEV_ID_82541GI_MOBILE:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	case E1000_DEV_ID_82544EI_COPPER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	case E1000_DEV_ID_82544EI_FIBER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	case E1000_DEV_ID_82544GC_COPPER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	case E1000_DEV_ID_82544GC_LOM:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	case E1000_DEV_ID_82545EM_COPPER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	case E1000_DEV_ID_82545EM_FIBER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	case E1000_DEV_ID_82546EB_COPPER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	case E1000_DEV_ID_82546EB_FIBER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		return true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		return false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
static const struct net_device_ops e1000_netdev_ops = {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	.ndo_open		= e1000_open,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	.ndo_stop		= e1000_close,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	.ndo_start_xmit		= e1000_xmit_frame,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	.ndo_get_stats		= e1000_get_stats,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	.ndo_set_rx_mode	= e1000_set_rx_mode,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	.ndo_set_mac_address	= e1000_set_mac,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	.ndo_tx_timeout 	= e1000_tx_timeout,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	.ndo_change_mtu		= e1000_change_mtu,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	.ndo_do_ioctl		= e1000_ioctl,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	.ndo_validate_addr	= eth_validate_addr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
#ifdef CONFIG_NET_POLL_CONTROLLER
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	.ndo_poll_controller	= e1000_netpoll,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
};
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
 * e1000_init_hw_struct - initialize members of hw struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
 * @adapter: board private struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
 * @hw: structure used by e1000_hw.c
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
 * Factors out initialization of the e1000_hw struct to its own function
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
 * that can be called very early at init (just after struct allocation).
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
 * Fields are initialized based on PCI device information and
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
 * OS network device settings (MTU size).
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
 * Returns negative error codes if MAC type setup fails.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
static int e1000_init_hw_struct(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
				struct e1000_hw *hw)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	/* PCI config space info */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	hw->vendor_id = pdev->vendor;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	hw->device_id = pdev->device;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	hw->subsystem_id = pdev->subsystem_device;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	hw->revision_id = pdev->revision;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	hw->max_frame_size = adapter->netdev->mtu +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	/* identify the MAC */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	if (e1000_set_mac_type(hw)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		e_err(probe, "Unknown MAC Type\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
		return -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	case e1000_82541:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	case e1000_82547:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	case e1000_82541_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	case e1000_82547_rev_2:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		hw->phy_init_script = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	e1000_set_media_type(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	e1000_get_bus_info(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	hw->wait_autoneg_complete = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	hw->tbi_compatibility_en = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	hw->adaptive_ifs = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	/* Copper options */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (hw->media_type == e1000_media_type_copper) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		hw->mdix = AUTO_ALL_MODES;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
		hw->disable_polarity_correction = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		hw->master_slave = E1000_MASTER_SLAVE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
 * e1000_probe - Device Initialization Routine
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
 * @pdev: PCI device information struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
 * @ent: entry in e1000_pci_tbl
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
 * Returns 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
 * e1000_probe initializes an adapter identified by a pci_dev structure.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
 * The OS initialization, configuring of the adapter private structure,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
 * and a hardware reset occur.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
static int __devinit e1000_probe(struct pci_dev *pdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
				 const struct pci_device_id *ent)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	struct net_device *netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	struct e1000_adapter *adapter;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	struct e1000_hw *hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	static int cards_found = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	int i, err, pci_using_dac;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	u16 eeprom_data = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	int bars, need_ioport;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	/* do not allocate ioport bars when not needed */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	need_ioport = e1000_is_need_ioport(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	if (need_ioport) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		err = pci_enable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		err = pci_enable_device_mem(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		goto err_pci_reg;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	pci_set_master(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	err = pci_save_state(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		goto err_alloc_etherdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	err = -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	if (!netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		goto err_alloc_etherdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	SET_NETDEV_DEV(netdev, &pdev->dev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	pci_set_drvdata(pdev, netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	adapter->netdev = netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	adapter->pdev = pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	adapter->msg_enable = (1 << debug) - 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	adapter->bars = bars;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	adapter->need_ioport = need_ioport;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	hw->back = adapter;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	err = -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	if (!hw->hw_addr)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		goto err_ioremap;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	if (adapter->need_ioport) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		for (i = BAR_1; i <= BAR_5; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
			if (pci_resource_len(pdev, i) == 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
				continue;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
				hw->io_base = pci_resource_start(pdev, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	/* make ready for any if (hw->...) below */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	err = e1000_init_hw_struct(adapter, hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		goto err_sw_init;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	 * there is a workaround being applied below that limits
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	 * 64-bit DMA addresses to 64-bit hardware.  There are some
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	pci_using_dac = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	if ((hw->bus_type == e1000_bus_type_pcix) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		 * according to DMA-API-HOWTO, coherent calls will always
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
		 * succeed if the set call did
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		pci_using_dac = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
			pr_err("No usable DMA config, aborting\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
			goto err_dma;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	netdev->netdev_ops = &e1000_netdev_ops;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	e1000_set_ethtool_ops(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	netdev->watchdog_timeo = 5 * HZ;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	adapter->bd_number = cards_found;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	/* setup the private structure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	err = e1000_sw_init(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		goto err_sw_init;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	err = -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	if (hw->mac_type >= e1000_82543) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		netdev->features = NETIF_F_SG |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
				   NETIF_F_HW_CSUM |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
				   NETIF_F_HW_VLAN_TX |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				   NETIF_F_HW_VLAN_RX |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				   NETIF_F_HW_VLAN_FILTER;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	if ((hw->mac_type >= e1000_82544) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	   (hw->mac_type != e1000_82547))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		netdev->features |= NETIF_F_TSO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	if (pci_using_dac) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		netdev->features |= NETIF_F_HIGHDMA;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		netdev->vlan_features |= NETIF_F_HIGHDMA;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	netdev->vlan_features |= NETIF_F_TSO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	netdev->vlan_features |= NETIF_F_HW_CSUM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	netdev->vlan_features |= NETIF_F_SG;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	/* initialize eeprom parameters */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	if (e1000_init_eeprom_params(hw)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		e_err(probe, "EEPROM initialization failed\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		goto err_eeprom;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	/* before reading the EEPROM, reset the controller to
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	 * put the device in a known good starting state */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	e1000_reset_hw(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	/* make sure the EEPROM is good */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	if (e1000_validate_eeprom_checksum(hw) < 0) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		e1000_dump_eeprom(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		 * set MAC address to all zeroes to invalidate and temporary
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
		 * disable this device for the user. This blocks regular
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		 * traffic while still permitting ethtool ioctls from reaching
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		 * the hardware as well as allowing the user to run the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		 * interface after manually setting a hw addr using
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 * `ip set address`
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		memset(hw->mac_addr, 0, netdev->addr_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		/* copy the MAC address out of the EEPROM */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		if (e1000_read_mac_addr(hw))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
			e_err(probe, "EEPROM Read Error\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	/* don't block initalization here due to bad MAC address */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	if (!is_valid_ether_addr(netdev->perm_addr))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		e_err(probe, "Invalid MAC Address\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	init_timer(&adapter->tx_fifo_stall_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	init_timer(&adapter->watchdog_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	adapter->watchdog_timer.function = e1000_watchdog;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	adapter->watchdog_timer.data = (unsigned long) adapter;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	init_timer(&adapter->phy_info_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	adapter->phy_info_timer.function = e1000_update_phy_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	adapter->phy_info_timer.data = (unsigned long)adapter;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	INIT_WORK(&adapter->fifo_stall_task, e1000_82547_tx_fifo_stall_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	INIT_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	e1000_check_options(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	/* Initial Wake on LAN setting
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	 * If APM wake is enabled in the EEPROM,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	 * enable the ACPI Magic Packet filter
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	case e1000_82542_rev2_0:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	case e1000_82542_rev2_1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	case e1000_82543:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	case e1000_82544:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		e1000_read_eeprom(hw,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	case e1000_82546:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	case e1000_82546_rev_3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
			e1000_read_eeprom(hw,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		/* Fall Through */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		e1000_read_eeprom(hw,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	if (eeprom_data & eeprom_apme_mask)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		adapter->eeprom_wol |= E1000_WUFC_MAG;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	/* now that we have the eeprom settings, apply the special cases
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	 * where the eeprom may be wrong or the board simply won't support
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	 * wake on lan on a particular port */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	switch (pdev->device) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	case E1000_DEV_ID_82546GB_PCIE:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		adapter->eeprom_wol = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	case E1000_DEV_ID_82546EB_FIBER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	case E1000_DEV_ID_82546GB_FIBER:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		/* Wake events only supported on port A for dual fiber
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		 * regardless of eeprom setting */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			adapter->eeprom_wol = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		/* if quad port adapter, disable WoL on all but port A */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		if (global_quad_port_a != 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			adapter->eeprom_wol = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
			adapter->quad_port_a = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		/* Reset for multiple quad port adapters */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		if (++global_quad_port_a == 4)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
			global_quad_port_a = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	/* initialize the wol settings based on the eeprom settings */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	adapter->wol = adapter->eeprom_wol;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	/* reset the hardware with the new settings */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	strcpy(netdev->name, "eth%d");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	err = register_netdev(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		goto err_register;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	/* print bus type/speed/width info */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	       netdev->dev_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	/* carrier off reporting is important to ethtool even BEFORE open */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	netif_carrier_off(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	cards_found++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
err_register:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
err_eeprom:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	e1000_phy_hw_reset(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	if (hw->flash_address)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		iounmap(hw->flash_address);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	kfree(adapter->tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	kfree(adapter->rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
err_dma:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
err_sw_init:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	iounmap(hw->hw_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
err_ioremap:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	free_netdev(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
err_alloc_etherdev:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	pci_release_selected_regions(pdev, bars);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
err_pci_reg:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	pci_disable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
 * e1000_remove - Device Removal Routine
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
 * @pdev: PCI device information struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
 * e1000_remove is called by the PCI subsystem to alert the driver
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
 * that it should release a PCI device.  The could be caused by a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
 * Hot-Plug event, or because the driver is going to be removed from
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
 * memory.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
static void __devexit e1000_remove(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	set_bit(__E1000_DOWN, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	del_timer_sync(&adapter->tx_fifo_stall_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	del_timer_sync(&adapter->watchdog_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	del_timer_sync(&adapter->phy_info_timer);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	cancel_work_sync(&adapter->reset_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	e1000_release_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	unregister_netdev(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	e1000_phy_hw_reset(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	kfree(adapter->tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	kfree(adapter->rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	iounmap(hw->hw_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	if (hw->flash_address)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		iounmap(hw->flash_address);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	pci_release_selected_regions(pdev, adapter->bars);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	free_netdev(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	pci_disable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
 * @adapter: board private structure to initialize
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
 * e1000_sw_init initializes the Adapter private data structure.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
 * e1000_init_hw_struct MUST be called before this function
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	adapter->num_tx_queues = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	adapter->num_rx_queues = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	if (e1000_alloc_queues(adapter)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		e_err(probe, "Unable to allocate memory for queues\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	/* Explicitly disable IRQ since the NIC can be in any state. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	e1000_irq_disable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	spin_lock_init(&adapter->stats_lock);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	set_bit(__E1000_DOWN, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
 * e1000_alloc_queues - Allocate memory for all rings
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
 * @adapter: board private structure to initialize
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
 * We allocate one ring per queue at run-time since we don't know the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 * number of queues at compile-time.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	if (!adapter->tx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	if (!adapter->rx_ring) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		kfree(adapter->tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	return E1000_SUCCESS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
 * e1000_open - Called when a network interface is made active
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
 * Returns 0 on success, negative value on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
 * The open entry point is called when a network interface is made
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
 * active by the system (IFF_UP).  At this point all resources needed
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
 * for transmit and receive operations are allocated, the interrupt
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
 * handler is registered with the OS, the watchdog timer is started,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
 * and the stack is notified that the interface is ready.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
static int e1000_open(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	int err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	/* disallow open during test */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	if (test_bit(__E1000_TESTING, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		return -EBUSY;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	netif_carrier_off(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	/* allocate transmit descriptors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	err = e1000_setup_all_tx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		goto err_setup_tx;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	/* allocate receive descriptors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	err = e1000_setup_all_rx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		goto err_setup_rx;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	e1000_power_up_phy(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	if ((hw->mng_cookie.status &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		e1000_update_mng_vlan(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	/* before we allocate an interrupt, we must be ready to handle it.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	 * as soon as we call pci_request_irq, so we have to setup our
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	 * clean_rx handler before we do so.  */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	e1000_configure(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	err = e1000_request_irq(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		goto err_req_irq;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	/* From here on the code is the same as e1000_up() */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	clear_bit(__E1000_DOWN, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	napi_enable(&adapter->napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	netif_start_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	/* fire a link status change interrupt to start the watchdog */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	ew32(ICS, E1000_ICS_LSC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	return E1000_SUCCESS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
err_req_irq:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	e1000_power_down_phy(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	e1000_free_all_rx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
err_setup_rx:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	e1000_free_all_tx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
err_setup_tx:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
 * e1000_close - Disables a network interface
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
 * Returns 0, this is not allowed to fail
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
 * The close entry point is called when an interface is de-activated
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
 * by the OS.  The hardware is still under the drivers control, but
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
 * needs to be disabled.  A global MAC reset is issued to stop the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
 * hardware, and all transmit and receive resources are freed.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
static int e1000_close(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	e1000_power_down_phy(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	e1000_free_irq(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	e1000_free_all_tx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	e1000_free_all_rx_resources(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	/* kill manageability vlan ID if supported, but not if a vlan with
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	 * the same ID is registered on the host OS (let 8021q kill it) */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	if ((hw->mng_cookie.status &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	     !(adapter->vlgrp &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 * @adapter: address of board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 * @start: address of beginning of memory
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 * @len: length of memory
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
				  unsigned long len)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	unsigned long begin = (unsigned long)start;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	unsigned long end = begin + len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	/* First rev 82545 and 82546 need to not allow any memory
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	 * write location to cross 64k boundary due to errata 23 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	if (hw->mac_type == e1000_82545 ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	    hw->mac_type == e1000_82546) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	return true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
 * @txdr:    tx descriptor ring (for a specific queue) to setup
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
 * Return 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
				    struct e1000_tx_ring *txdr)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	int size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	size = sizeof(struct e1000_buffer) * txdr->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	txdr->buffer_info = vmalloc(size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	if (!txdr->buffer_info) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		      "ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	memset(txdr->buffer_info, 0, size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	/* round up to nearest 4K */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	txdr->size = ALIGN(txdr->size, 4096);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
					GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	if (!txdr->desc) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
setup_tx_desc_die:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		vfree(txdr->buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		      "ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	/* Fix for errata 23, can't cross 64kB boundary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		void *olddesc = txdr->desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		dma_addr_t olddma = txdr->dma;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		      txdr->size, txdr->desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		/* Try again, without freeing the previous */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
						&txdr->dma, GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		/* Failed allocation, critical failure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		if (!txdr->desc) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
			goto setup_tx_desc_die;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
			/* give up */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
					  txdr->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			e_err(probe, "Unable to allocate aligned memory "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
			      "for the transmit descriptor ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
			vfree(txdr->buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
			return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
			/* Free old allocation, new allocation was successful */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	memset(txdr->desc, 0, txdr->size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	txdr->next_to_use = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	txdr->next_to_clean = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
 * 				  (Descriptors) for all queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
 * Return 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	int i, err = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	for (i = 0; i < adapter->num_tx_queues; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
			for (i-- ; i >= 0; i--)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
				e1000_free_tx_resources(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
							&adapter->tx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
 * Configure the Tx unit of the MAC after a reset.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
static void e1000_configure_tx(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	u64 tdba;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	u32 tdlen, tctl, tipg;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	u32 ipgr1, ipgr2;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	/* Setup the HW Tx Head and Tail descriptor pointers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	switch (adapter->num_tx_queues) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	case 1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		tdba = adapter->tx_ring[0].dma;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		tdlen = adapter->tx_ring[0].count *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
			sizeof(struct e1000_tx_desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		ew32(TDLEN, tdlen);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		ew32(TDBAH, (tdba >> 32));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		ew32(TDT, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		ew32(TDH, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	/* Set the default values for the Tx Inter Packet Gap timer */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	if ((hw->media_type == e1000_media_type_fiber ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	     hw->media_type == e1000_media_type_internal_serdes))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	case e1000_82542_rev2_0:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	case e1000_82542_rev2_1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		tipg = DEFAULT_82542_TIPG_IPGT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	ew32(TIPG, tipg);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	/* Set the Tx Interrupt Delay register */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	ew32(TIDV, adapter->tx_int_delay);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	if (hw->mac_type >= e1000_82540)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		ew32(TADV, adapter->tx_abs_int_delay);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	/* Program the Transmit Control Register */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	tctl = er32(TCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	tctl &= ~E1000_TCTL_CT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	e1000_config_collision_dist(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	/* Setup Transmit Descriptor Settings for eop descriptor */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	/* only set IDE if we are delaying interrupts using the timers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	if (adapter->tx_int_delay)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	if (hw->mac_type < e1000_82543)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	/* Cache if we're 82544 running in PCI-X because we'll
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	 * need this to apply a workaround later in the send path. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	if (hw->mac_type == e1000_82544 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	    hw->bus_type == e1000_bus_type_pcix)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		adapter->pcix_82544 = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	ew32(TCTL, tctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
 * Returns 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
				    struct e1000_rx_ring *rxdr)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	int size, desc_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	size = sizeof(struct e1000_buffer) * rxdr->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	rxdr->buffer_info = vmalloc(size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	if (!rxdr->buffer_info) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		      "ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	memset(rxdr->buffer_info, 0, size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	desc_len = sizeof(struct e1000_rx_desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	/* Round up to nearest 4K */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	rxdr->size = rxdr->count * desc_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	rxdr->size = ALIGN(rxdr->size, 4096);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
					GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	if (!rxdr->desc) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		      "ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
setup_rx_desc_die:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		vfree(rxdr->buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		return -ENOMEM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	/* Fix for errata 23, can't cross 64kB boundary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		void *olddesc = rxdr->desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		dma_addr_t olddma = rxdr->dma;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		      rxdr->size, rxdr->desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		/* Try again, without freeing the previous */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
						&rxdr->dma, GFP_KERNEL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
		/* Failed allocation, critical failure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		if (!rxdr->desc) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			e_err(probe, "Unable to allocate memory for the Rx "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
			      "descriptor ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			goto setup_rx_desc_die;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			/* give up */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
					  rxdr->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
			e_err(probe, "Unable to allocate aligned memory for "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			      "the Rx descriptor ring\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
			goto setup_rx_desc_die;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
			/* Free old allocation, new allocation was successful */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
					  olddma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	memset(rxdr->desc, 0, rxdr->size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	rxdr->next_to_clean = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	rxdr->next_to_use = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	rxdr->rx_skb_top = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
 * 				  (Descriptors) for all queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
 * Return 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	int i, err = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	for (i = 0; i < adapter->num_rx_queues; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
			for (i-- ; i >= 0; i--)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
				e1000_free_rx_resources(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
							&adapter->rx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 * e1000_setup_rctl - configure the receive control registers
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 * @adapter: Board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
static void e1000_setup_rctl(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	u32 rctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	if (hw->tbi_compatibility_on == 1)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		rctl |= E1000_RCTL_SBP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		rctl &= ~E1000_RCTL_SBP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		rctl &= ~E1000_RCTL_LPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		rctl |= E1000_RCTL_LPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	/* Setup buffer sizes */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	rctl &= ~E1000_RCTL_SZ_4096;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	rctl |= E1000_RCTL_BSEX;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	switch (adapter->rx_buffer_len) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		case E1000_RXBUFFER_2048:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			rctl |= E1000_RCTL_SZ_2048;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			rctl &= ~E1000_RCTL_BSEX;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		case E1000_RXBUFFER_4096:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			rctl |= E1000_RCTL_SZ_4096;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		case E1000_RXBUFFER_8192:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
			rctl |= E1000_RCTL_SZ_8192;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		case E1000_RXBUFFER_16384:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
			rctl |= E1000_RCTL_SZ_16384;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
 * Configure the Rx unit of the MAC after a reset.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
static void e1000_configure_rx(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	u64 rdba;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	u32 rdlen, rctl, rxcsum;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		rdlen = adapter->rx_ring[0].count *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		        sizeof(struct e1000_rx_desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		rdlen = adapter->rx_ring[0].count *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		        sizeof(struct e1000_rx_desc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		adapter->clean_rx = e1000_clean_rx_irq;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	/* disable receives while setting up the descriptors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	/* set the Receive Delay Timer Register */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	ew32(RDTR, adapter->rx_int_delay);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	if (hw->mac_type >= e1000_82540) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		ew32(RADV, adapter->rx_abs_int_delay);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
		if (adapter->itr_setting != 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			ew32(ITR, 1000000000 / (adapter->itr * 256));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	 * the Base and Length of the Rx Descriptor Ring */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	switch (adapter->num_rx_queues) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	case 1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		rdba = adapter->rx_ring[0].dma;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		ew32(RDLEN, rdlen);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		ew32(RDBAH, (rdba >> 32));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		ew32(RDT, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
		ew32(RDH, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	if (hw->mac_type >= e1000_82543) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		rxcsum = er32(RXCSUM);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		if (adapter->rx_csum)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			rxcsum |= E1000_RXCSUM_TUOFL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
			/* don't need to clear IPPCSE as it defaults to 0 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			rxcsum &= ~E1000_RXCSUM_TUOFL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		ew32(RXCSUM, rxcsum);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	/* Enable Receives */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
 * e1000_free_tx_resources - Free Tx Resources per Queue
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
 * @tx_ring: Tx descriptor ring for a specific queue
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
 * Free all transmit software resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
				    struct e1000_tx_ring *tx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	e1000_clean_tx_ring(adapter, tx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
	vfree(tx_ring->buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	tx_ring->buffer_info = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
			  tx_ring->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	tx_ring->desc = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
 * Free all transmit software resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	for (i = 0; i < adapter->num_tx_queues; i++)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
					     struct e1000_buffer *buffer_info)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	if (buffer_info->dma) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		if (buffer_info->mapped_as_page)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
				       buffer_info->length, DMA_TO_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
					 buffer_info->length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
					 DMA_TO_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
		buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	if (buffer_info->skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		dev_kfree_skb_any(buffer_info->skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	buffer_info->time_stamp = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	/* buffer_info must be completely set up in the transmit path */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 * e1000_clean_tx_ring - Free Tx Buffers
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 * @tx_ring: ring to be cleaned
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
				struct e1000_tx_ring *tx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	unsigned long size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	/* Free all the Tx ring sk_buffs */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	for (i = 0; i < tx_ring->count; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	size = sizeof(struct e1000_buffer) * tx_ring->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	memset(tx_ring->buffer_info, 0, size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	/* Zero out the descriptor ring */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	memset(tx_ring->desc, 0, tx_ring->size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	tx_ring->next_to_use = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	tx_ring->next_to_clean = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	tx_ring->last_tx_tso = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	writel(0, hw->hw_addr + tx_ring->tdh);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	writel(0, hw->hw_addr + tx_ring->tdt);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	for (i = 0; i < adapter->num_tx_queues; i++)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
 * e1000_free_rx_resources - Free Rx Resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
 * @rx_ring: ring to clean the resources from
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
 * Free all receive software resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
				    struct e1000_rx_ring *rx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	e1000_clean_rx_ring(adapter, rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	vfree(rx_ring->buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	rx_ring->buffer_info = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
			  rx_ring->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	rx_ring->desc = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
 * Free all receive software resources
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	for (i = 0; i < adapter->num_rx_queues; i++)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
 * @rx_ring: ring to free buffers from
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
				struct e1000_rx_ring *rx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	unsigned long size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	/* Free all the Rx ring sk_buffs */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	for (i = 0; i < rx_ring->count; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
		buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		if (buffer_info->dma &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		    adapter->clean_rx == e1000_clean_rx_irq) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
			dma_unmap_single(&pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
			                 buffer_info->length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
					 DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		} else if (buffer_info->dma &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
			dma_unmap_page(&pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
				       buffer_info->length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
				       DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		if (buffer_info->page) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
			put_page(buffer_info->page);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
			buffer_info->page = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
		if (buffer_info->skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			dev_kfree_skb(buffer_info->skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
			buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	/* there also may be some cached data from a chained receive */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	if (rx_ring->rx_skb_top) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
		dev_kfree_skb(rx_ring->rx_skb_top);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		rx_ring->rx_skb_top = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	size = sizeof(struct e1000_buffer) * rx_ring->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	memset(rx_ring->buffer_info, 0, size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	/* Zero out the descriptor ring */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	memset(rx_ring->desc, 0, rx_ring->size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	rx_ring->next_to_clean = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	rx_ring->next_to_use = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
	writel(0, hw->hw_addr + rx_ring->rdh);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	writel(0, hw->hw_addr + rx_ring->rdt);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	for (i = 0; i < adapter->num_rx_queues; i++)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
 * and memory write and invalidate disabled for certain operations
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	u32 rctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	e1000_pci_clear_mwi(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	rctl |= E1000_RCTL_RST;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	mdelay(5);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		e1000_clean_all_rx_rings(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	u32 rctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	rctl &= ~E1000_RCTL_RST;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	mdelay(5);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		e1000_pci_set_mwi(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	if (netif_running(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		/* No need to loop, because 82542 supports only 1 queue */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		e1000_configure_rx(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
 * e1000_set_mac - Change the Ethernet Address of the NIC
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
 * @p: pointer to an address structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
 * Returns 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
static int e1000_set_mac(struct net_device *netdev, void *p)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	struct sockaddr *addr = p;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	if (!is_valid_ether_addr(addr->sa_data))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		return -EADDRNOTAVAIL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	/* 82542 2.0 needs to be in reset to write receive address registers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	if (hw->mac_type == e1000_82542_rev2_0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
		e1000_enter_82542_rst(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	e1000_rar_set(hw, hw->mac_addr, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	if (hw->mac_type == e1000_82542_rev2_0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
		e1000_leave_82542_rst(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * The set_rx_mode entry point is called whenever the unicast or multicast
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 * address lists or the network interface flags are updated. This routine is
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 * responsible for configuring the hardware for proper unicast, multicast,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 * promiscuous mode, and all-multi behavior.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
static void e1000_set_rx_mode(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	struct netdev_hw_addr *ha;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	bool use_uc = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	u32 rctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	u32 hash_value;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	int i, rar_entries = E1000_RAR_ENTRIES;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	if (!mcarray) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
		e_err(probe, "memory allocation failed\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	/* Check for Promiscuous and All Multicast modes */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	if (netdev->flags & IFF_PROMISC) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		rctl &= ~E1000_RCTL_VFE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		if (netdev->flags & IFF_ALLMULTI)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			rctl |= E1000_RCTL_MPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			rctl &= ~E1000_RCTL_MPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		/* Enable VLAN filter if there is a VLAN */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		if (adapter->vlgrp)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
			rctl |= E1000_RCTL_VFE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	if (netdev_uc_count(netdev) > rar_entries - 1) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
		rctl |= E1000_RCTL_UPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	} else if (!(netdev->flags & IFF_PROMISC)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		rctl &= ~E1000_RCTL_UPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		use_uc = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	/* 82542 2.0 needs to be in reset to write receive address registers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	if (hw->mac_type == e1000_82542_rev2_0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		e1000_enter_82542_rst(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	/* load the first 14 addresses into the exact filters 1-14. Unicast
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	 * addresses take precedence to avoid disabling unicast filtering
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	 * when possible.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	 * RAR 0 is used for the station MAC adddress
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	 * if there are not 14 addresses, go ahead and clear the filters
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	i = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	if (use_uc)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
		netdev_for_each_uc_addr(ha, netdev) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
			if (i == rar_entries)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
			e1000_rar_set(hw, ha->addr, i++);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	netdev_for_each_mc_addr(ha, netdev) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		if (i == rar_entries) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
			/* load any remaining addresses into the hash table */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			u32 hash_reg, hash_bit, mta;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
			hash_reg = (hash_value >> 5) & 0x7F;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
			hash_bit = hash_value & 0x1F;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
			mta = (1 << hash_bit);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			mcarray[hash_reg] |= mta;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			e1000_rar_set(hw, ha->addr, i++);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	for (; i < rar_entries; i++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
		E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	/* write the hash table completely, write from bottom to avoid
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	 * both stupid write combining chipsets, and flushing each write */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		 * If we are on an 82544 has an errata where writing odd
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		 * offsets overwrites the previous even offset, but writing
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		 * backwards over the range solves the issue by always
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		 * writing the odd offset first
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	if (hw->mac_type == e1000_82542_rev2_0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		e1000_leave_82542_rst(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	kfree(mcarray);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
/* Need to wait a few seconds after link up to get diagnostic information from
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
 * the phy */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
static void e1000_update_phy_info(unsigned long data)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	schedule_work(&adapter->phy_info_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
static void e1000_update_phy_info_task(struct work_struct *work)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	struct e1000_adapter *adapter = container_of(work,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	                                             struct e1000_adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	                                             phy_info_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	rtnl_lock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	e1000_phy_get_info(hw, &adapter->phy_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	rtnl_unlock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
 * e1000_82547_tx_fifo_stall - Timer Call-back
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
 * @data: pointer to adapter cast into an unsigned long
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
static void e1000_82547_tx_fifo_stall(unsigned long data)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	schedule_work(&adapter->fifo_stall_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 * e1000_82547_tx_fifo_stall_task - task to complete work
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 * @work: work struct contained inside adapter struct
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	struct e1000_adapter *adapter = container_of(work,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	                                             struct e1000_adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	                                             fifo_stall_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	u32 tctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	rtnl_lock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	if (atomic_read(&adapter->tx_fifo_stall)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
		if ((er32(TDT) == er32(TDH)) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
		   (er32(TDFT) == er32(TDFH)) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		   (er32(TDFTS) == er32(TDFHS))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
			tctl = er32(TCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
			ew32(TDFT, adapter->tx_head_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
			ew32(TDFH, adapter->tx_head_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			ew32(TDFTS, adapter->tx_head_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
			ew32(TDFHS, adapter->tx_head_addr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
			ew32(TCTL, tctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
			E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
			adapter->tx_fifo_head = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			atomic_set(&adapter->tx_fifo_stall, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
			netif_wake_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	rtnl_unlock();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
bool e1000_has_link(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	bool link_active = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	/* get_link_status is set on LSC (link status) interrupt or
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	 * rx sequence error interrupt.  get_link_status will stay
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	 * false until the e1000_check_for_link establishes link
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	 * for copper adapters ONLY
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	switch (hw->media_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	case e1000_media_type_copper:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		if (hw->get_link_status) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
			e1000_check_for_link(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
			link_active = !hw->get_link_status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
			link_active = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	case e1000_media_type_fiber:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		e1000_check_for_link(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	case e1000_media_type_internal_serdes:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		e1000_check_for_link(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		link_active = hw->serdes_has_link;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	return link_active;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
 * e1000_watchdog - Timer Call-back
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
 * @data: pointer to adapter cast into an unsigned long
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
static void e1000_watchdog(unsigned long data)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	struct e1000_tx_ring *txdr = adapter->tx_ring;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	u32 link, tctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	link = e1000_has_link(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	if ((netif_carrier_ok(netdev)) && link)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
		goto link_up;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	if (link) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		if (!netif_carrier_ok(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
			u32 ctrl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			bool txb2b = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			/* update snapshot of PHY registers on LSC */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			e1000_get_speed_and_duplex(hw,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			                           &adapter->link_speed,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			                           &adapter->link_duplex);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			ctrl = er32(CTRL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			pr_info("%s NIC Link is Up %d Mbps %s, "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
				"Flow Control: %s\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
				netdev->name,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
				adapter->link_speed,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
				adapter->link_duplex == FULL_DUPLEX ?
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
				"Full Duplex" : "Half Duplex",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
				E1000_CTRL_TFCE) ? "TX" : "None")));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			/* adjust timeout factor according to speed/duplex */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
			adapter->tx_timeout_factor = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			switch (adapter->link_speed) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
			case SPEED_10:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
				txb2b = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
				adapter->tx_timeout_factor = 16;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			case SPEED_100:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
				txb2b = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
				/* maybe add some timeout factor ? */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			/* enable transmits in the hardware */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
			tctl = er32(TCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			tctl |= E1000_TCTL_EN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
			ew32(TCTL, tctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
			netif_carrier_on(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
				mod_timer(&adapter->phy_info_timer,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
				          round_jiffies(jiffies + 2 * HZ));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
			adapter->smartspeed = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		if (netif_carrier_ok(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
			adapter->link_speed = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
			adapter->link_duplex = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
			pr_info("%s NIC Link is Down\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
				netdev->name);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
			netif_carrier_off(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
			if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
				mod_timer(&adapter->phy_info_timer,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
				          round_jiffies(jiffies + 2 * HZ));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		e1000_smartspeed(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
link_up:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	e1000_update_stats(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	adapter->tpt_old = adapter->stats.tpt;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	adapter->colc_old = adapter->stats.colc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	adapter->gorcl_old = adapter->stats.gorcl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	adapter->gotcl_old = adapter->stats.gotcl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	e1000_update_adaptive(hw);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	if (!netif_carrier_ok(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
			/* We've lost link, so the controller stops DMA,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
			 * but we've got queued Tx work that's never going
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
			 * to get done, so reset controller to flush Tx.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			 * (Do the reset outside of interrupt context). */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
			adapter->tx_timeout_count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
			schedule_work(&adapter->reset_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
			/* return immediately since reset is imminent */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
			return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
	/* Simple mode for Interrupt Throttle Rate (ITR) */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		 * Total asymmetrical Tx or Rx gets ITR=8000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		 * everyone else is between 2000-8000.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		u32 dif = (adapter->gotcl > adapter->gorcl ?
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			    adapter->gotcl - adapter->gorcl :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			    adapter->gorcl - adapter->gotcl) / 10000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
		ew32(ITR, 1000000000 / (itr * 256));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	/* Cause software interrupt to ensure rx ring is cleaned */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	ew32(ICS, E1000_ICS_RXDMT0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	/* Force detection of hung controller every watchdog period */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	adapter->detect_tx_hung = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	/* Reset the timer */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		mod_timer(&adapter->watchdog_timer,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		          round_jiffies(jiffies + 2 * HZ));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
enum latency_range {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	lowest_latency = 0,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
	low_latency = 1,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	bulk_latency = 2,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	latency_invalid = 255
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
};
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
 * e1000_update_itr - update the dynamic ITR value based on statistics
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
 * @adapter: pointer to adapter
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
 * @itr_setting: current adapter->itr
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
 * @packets: the number of packets during this measurement interval
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
 * @bytes: the number of bytes during this measurement interval
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
 *      Stores a new ITR value based on packets and byte
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
 *      counts during the last interrupt.  The advantage of per interrupt
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
 *      computation is faster updates and more accurate ITR for the current
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
 *      traffic pattern.  Constants in this function were computed
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
 *      based on theoretical maximum wire speed and thresholds were set based
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
 *      on testing data as well as attempting to minimize response time
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
 *      while increasing bulk throughput.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
 *      this functionality is controlled by the InterruptThrottleRate module
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
 *      parameter (see e1000_param.c)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
				     u16 itr_setting, int packets, int bytes)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	unsigned int retval = itr_setting;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	if (unlikely(hw->mac_type < e1000_82540))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		goto update_itr_done;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	if (packets == 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		goto update_itr_done;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	switch (itr_setting) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	case lowest_latency:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		/* jumbo frames get bulk treatment*/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		if (bytes/packets > 8000)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			retval = bulk_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		else if ((packets < 5) && (bytes > 512))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			retval = low_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	case low_latency:  /* 50 usec aka 20000 ints/s */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
		if (bytes > 10000) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			/* jumbo frames need bulk latency setting */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			if (bytes/packets > 8000)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				retval = bulk_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			else if ((packets < 10) || ((bytes/packets) > 1200))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
				retval = bulk_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
			else if ((packets > 35))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
				retval = lowest_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		} else if (bytes/packets > 2000)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			retval = bulk_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		else if (packets <= 2 && bytes < 512)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
			retval = lowest_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	case bulk_latency: /* 250 usec aka 4000 ints/s */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
		if (bytes > 25000) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			if (packets > 35)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
				retval = low_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
		} else if (bytes < 6000) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
			retval = low_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
update_itr_done:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	return retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
static void e1000_set_itr(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	u16 current_itr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	u32 new_itr = adapter->itr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	if (unlikely(hw->mac_type < e1000_82540))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	if (unlikely(adapter->link_speed != SPEED_1000)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		current_itr = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		new_itr = 4000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		goto set_itr_now;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	adapter->tx_itr = e1000_update_itr(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	                            adapter->tx_itr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	                            adapter->total_tx_packets,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	                            adapter->total_tx_bytes);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		adapter->tx_itr = low_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	adapter->rx_itr = e1000_update_itr(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	                            adapter->rx_itr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	                            adapter->total_rx_packets,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	                            adapter->total_rx_bytes);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		adapter->rx_itr = low_latency;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	switch (current_itr) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	/* counts and packets in update_itr are dependent on these numbers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	case lowest_latency:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		new_itr = 70000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	case low_latency:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		new_itr = 20000; /* aka hwitr = ~200 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	case bulk_latency:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		new_itr = 4000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
set_itr_now:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	if (new_itr != adapter->itr) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		/* this attempts to bias the interrupt rate towards Bulk
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		 * by adding intermediate steps when interrupt rate is
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		 * increasing */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		new_itr = new_itr > adapter->itr ?
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		             min(adapter->itr + (new_itr >> 2), new_itr) :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		             new_itr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
		adapter->itr = new_itr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		ew32(ITR, 1000000000 / (new_itr * 256));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
#define E1000_TX_FLAGS_CSUM		0x00000001
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
#define E1000_TX_FLAGS_VLAN		0x00000002
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
#define E1000_TX_FLAGS_TSO		0x00000004
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
#define E1000_TX_FLAGS_IPV4		0x00000008
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
#define E1000_TX_FLAGS_VLAN_SHIFT	16
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
static int e1000_tso(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	struct e1000_context_desc *context_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	u32 cmd_length = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	u16 ipcse = 0, tucse, mss;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	int err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	if (skb_is_gso(skb)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		if (skb_header_cloned(skb)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
				return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
		mss = skb_shinfo(skb)->gso_size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		if (skb->protocol == htons(ETH_P_IP)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			struct iphdr *iph = ip_hdr(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
			iph->tot_len = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
			iph->check = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
								 iph->daddr, 0,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
								 IPPROTO_TCP,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
								 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			cmd_length = E1000_TXD_CMD_IP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
			ipcse = skb_transport_offset(skb) - 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
			ipv6_hdr(skb)->payload_len = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
			tcp_hdr(skb)->check =
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
						 &ipv6_hdr(skb)->daddr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
						 0, IPPROTO_TCP, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
			ipcse = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		ipcss = skb_network_offset(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		tucss = skb_transport_offset(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
		tucse = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		i = tx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		context_desc->upper_setup.tcp_fields.tucss = tucss;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
		context_desc->upper_setup.tcp_fields.tucso = tucso;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		buffer_info->time_stamp = jiffies;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		buffer_info->next_to_watch = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		if (++i == tx_ring->count) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		tx_ring->next_to_use = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		return true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	return false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
static bool e1000_tx_csum(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	struct e1000_context_desc *context_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	u8 css;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	u32 cmd_len = E1000_TXD_CMD_DEXT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
	if (skb->ip_summed != CHECKSUM_PARTIAL)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		return false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	switch (skb->protocol) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	case cpu_to_be16(ETH_P_IP):
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
			cmd_len |= E1000_TXD_CMD_TCP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	case cpu_to_be16(ETH_P_IPV6):
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		/* XXX not handling all IPV6 headers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
			cmd_len |= E1000_TXD_CMD_TCP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		if (unlikely(net_ratelimit()))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
			e_warn(drv, "checksum_partial proto=%x!\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			       skb->protocol);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	css = skb_transport_offset(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	i = tx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	context_desc->lower_setup.ip_config = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	context_desc->upper_setup.tcp_fields.tucss = css;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	context_desc->upper_setup.tcp_fields.tucso =
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		css + skb->csum_offset;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	context_desc->upper_setup.tcp_fields.tucse = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	context_desc->tcp_seg_setup.data = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	buffer_info->time_stamp = jiffies;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	buffer_info->next_to_watch = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	if (unlikely(++i == tx_ring->count)) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	tx_ring->next_to_use = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	return true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
#define E1000_MAX_TXD_PWR	12
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
static int e1000_tx_map(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			struct e1000_tx_ring *tx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
			struct sk_buff *skb, unsigned int first,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
			unsigned int max_per_txd, unsigned int nr_frags,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
			unsigned int mss)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	unsigned int len = skb_headlen(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	unsigned int offset = 0, size, count = 0, i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	unsigned int f;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	i = tx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
	while (len) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		size = min(len, max_per_txd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		/* Workaround for Controller erratum --
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		 * descriptor for non-tso packet in a linear SKB that follows a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		 * tso gets written back prematurely before the data is fully
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		 * DMA'd to the controller */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		if (!skb->data_len && tx_ring->last_tx_tso &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		    !skb_is_gso(skb)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
			tx_ring->last_tx_tso = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
			size -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		/* Workaround for premature desc write-backs
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		 * in TSO mode.  Append 4-byte sentinel desc */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		if (unlikely(mss && !nr_frags && size == len && size > 8))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
			size -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		/* work-around for errata 10 and it applies
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		 * to all controllers in PCI-X mode
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		 * The fix is to make sure that the first descriptor of a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		                (size > 2015) && count == 0))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		        size = 2015;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
		 * terminating buffers within evenly-aligned dwords. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
		if (unlikely(adapter->pcix_82544 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		   size > 4))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
			size -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		buffer_info->length = size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		/* set time_stamp *before* dma to help avoid a possible race */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		buffer_info->time_stamp = jiffies;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		buffer_info->mapped_as_page = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		buffer_info->dma = dma_map_single(&pdev->dev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
						  skb->data + offset,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
						  size,	DMA_TO_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
			goto dma_error;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		buffer_info->next_to_watch = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		len -= size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
		offset += size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
		count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		if (len) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
			i++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
			if (unlikely(i == tx_ring->count))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
				i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	for (f = 0; f < nr_frags; f++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		struct skb_frag_struct *frag;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		frag = &skb_shinfo(skb)->frags[f];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		len = frag->size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
		offset = frag->page_offset;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		while (len) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
			i++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			if (unlikely(i == tx_ring->count))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
				i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
			buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
			size = min(len, max_per_txd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			/* Workaround for premature desc write-backs
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			 * in TSO mode.  Append 4-byte sentinel desc */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
				size -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
			/* Workaround for potential 82544 hang in PCI-X.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
			 * Avoid terminating buffers within evenly-aligned
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
			 * dwords. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
			if (unlikely(adapter->pcix_82544 &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
			    !((unsigned long)(page_to_phys(frag->page) + offset
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
			                      + size - 1) & 4) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
			    size > 4))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
				size -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
			buffer_info->length = size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
			buffer_info->time_stamp = jiffies;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
			buffer_info->mapped_as_page = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
							offset,	size,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
							DMA_TO_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
				goto dma_error;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
			buffer_info->next_to_watch = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
			len -= size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
			offset += size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
			count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	tx_ring->buffer_info[i].skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	tx_ring->buffer_info[first].next_to_watch = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	return count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
dma_error:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	dev_err(&pdev->dev, "TX DMA map failed\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	if (count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
		count--;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	while (count--) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		if (i==0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
			i += tx_ring->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		i--;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
static void e1000_tx_queue(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
			   struct e1000_tx_ring *tx_ring, int tx_flags,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
			   int count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	struct e1000_tx_desc *tx_desc = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		             E1000_TXD_CMD_TSE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		txd_lower |= E1000_TXD_CMD_VLE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	i = tx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	while (count--) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		tx_desc = E1000_TX_DESC(*tx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		tx_desc->lower.data =
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
			cpu_to_le32(txd_lower | buffer_info->length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		tx_desc->upper.data = cpu_to_le32(txd_upper);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		if (unlikely(++i == tx_ring->count)) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	/* Force memory writes to complete before letting h/w
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	 * know there are new descriptors to fetch.  (Only
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	 * applicable for weak-ordered memory model archs,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	 * such as IA-64). */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	wmb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	tx_ring->next_to_use = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	writel(i, hw->hw_addr + tx_ring->tdt);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	/* we need this if more than one processor can write to our tail
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	 * at a time, it syncronizes IO on IA64/Altix systems */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	mmiowb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
 * 82547 workaround to avoid controller hang in half-duplex environment.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
 * The workaround is to avoid queuing a large packet that would span
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
 * the internal Tx FIFO ring boundary by notifying the stack to resend
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
 * to the beginning of the Tx FIFO.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
#define E1000_FIFO_HDR			0x10
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
#define E1000_82547_PAD_LEN		0x3E0
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
				       struct sk_buff *skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	if (adapter->link_duplex != HALF_DUPLEX)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		goto no_fifo_stall_required;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	if (atomic_read(&adapter->tx_fifo_stall))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		return 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		atomic_set(&adapter->tx_fifo_stall, 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		return 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
no_fifo_stall_required:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	adapter->tx_fifo_head += skb_fifo_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
	netif_stop_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	/* Herbert's original patch had:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	 *  smp_mb__after_netif_stop_queue();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	 * but since that doesn't exist yet, just open code it. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	smp_mb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	/* We need to check again in a case another CPU has just
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	 * made room available. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		return -EBUSY;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	/* A reprieve! */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	netif_start_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	++adapter->restart_queue;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
static int e1000_maybe_stop_tx(struct net_device *netdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
                               struct e1000_tx_ring *tx_ring, int size)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
		return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	return __e1000_maybe_stop_tx(netdev, size);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
				    struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	struct e1000_tx_ring *tx_ring;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	unsigned int tx_flags = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	unsigned int len = skb_headlen(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	unsigned int nr_frags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	unsigned int mss;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	int count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	int tso;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	unsigned int f;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	/* This goes back to the question of how to logically map a tx queue
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	 * to a flow.  Right now, performance is impacted slightly negatively
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	 * if using multiple tx queues.  If the stack breaks away from a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	 * single qdisc implementation, we can look at this again. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	tx_ring = adapter->tx_ring;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	if (unlikely(skb->len <= 0)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		dev_kfree_skb_any(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		return NETDEV_TX_OK;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	mss = skb_shinfo(skb)->gso_size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	/* The controller does a simple calculation to
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	 * make sure there is enough room in the FIFO before
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	 * initiating the DMA for each buffer.  The calc is:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	 * 4 = ceil(buffer len/mss).  To make sure we don't
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	 * overrun the FIFO, adjust the max buffer len if mss
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	 * drops. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	if (mss) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		u8 hdr_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		max_per_txd = min(mss << 2, max_per_txd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		max_txd_pwr = fls(max_per_txd) - 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		if (skb->data_len && hdr_len == len) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
			switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
				unsigned int pull_size;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
			case e1000_82544:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
				/* Make sure we have room to chop off 4 bytes,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
				 * and that the end alignment will work out to
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
				 * this hardware's requirements
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
				 * NOTE: this is a TSO only workaround
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
				 * if end byte alignment not correct move us
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
				 * into the next dword */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
					break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
				/* fall through */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
				pull_size = min((unsigned int)4, skb->data_len);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
				if (!__pskb_pull_tail(skb, pull_size)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
					e_err(drv, "__pskb_pull_tail "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
					      "failed.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
					dev_kfree_skb_any(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
					return NETDEV_TX_OK;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
				}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
				len = skb_headlen(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
			default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
				/* do nothing */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	/* reserve a descriptor for the offload context */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	/* Controller Erratum workaround */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	count += TXD_USE_COUNT(len, max_txd_pwr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	if (adapter->pcix_82544)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	/* work-around for errata 10 and it applies to all controllers
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	 * in PCI-X mode, so add one more descriptor to the count
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
			(len > 2015)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	nr_frags = skb_shinfo(skb)->nr_frags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	for (f = 0; f < nr_frags; f++)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
				       max_txd_pwr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	if (adapter->pcix_82544)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		count += nr_frags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	/* need: count + 2 desc gap to keep tail from touching
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	 * head, otherwise try next time */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		return NETDEV_TX_BUSY;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	if (unlikely(hw->mac_type == e1000_82547)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
			netif_stop_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
			if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
				mod_timer(&adapter->tx_fifo_stall_timer,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
				          jiffies + 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
			return NETDEV_TX_BUSY;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	if (unlikely(vlan_tx_tag_present(skb))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		tx_flags |= E1000_TX_FLAGS_VLAN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	first = tx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	tso = e1000_tso(adapter, tx_ring, skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	if (tso < 0) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
		dev_kfree_skb_any(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
		return NETDEV_TX_OK;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	if (likely(tso)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		if (likely(hw->mac_type != e1000_82544))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			tx_ring->last_tx_tso = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		tx_flags |= E1000_TX_FLAGS_TSO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		tx_flags |= E1000_TX_FLAGS_CSUM;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	if (likely(skb->protocol == htons(ETH_P_IP)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		tx_flags |= E1000_TX_FLAGS_IPV4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	                     nr_frags, mss);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	if (count) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		/* Make sure there is space in the ring for the next send. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		dev_kfree_skb_any(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		tx_ring->buffer_info[first].time_stamp = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		tx_ring->next_to_use = first;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	return NETDEV_TX_OK;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
 * e1000_tx_timeout - Respond to a Tx Hang
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
static void e1000_tx_timeout(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	/* Do the reset outside of interrupt context */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	adapter->tx_timeout_count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	schedule_work(&adapter->reset_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
static void e1000_reset_task(struct work_struct *work)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	struct e1000_adapter *adapter =
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
		container_of(work, struct e1000_adapter, reset_task);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	e1000_reinit_safe(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
 * e1000_get_stats - Get System Network Statistics
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
 * Returns the address of the device statistics structure.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
 * The statistics are actually updated from the timer callback.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	/* only return the current stats */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	return &netdev->stats;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
 * e1000_change_mtu - Change the Maximum Transfer Unit
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
 * @netdev: network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
 * @new_mtu: new value for maximum frame size
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
 * Returns 0 on success, negative on failure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		e_err(probe, "Invalid MTU setting\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		return -EINVAL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	/* Adapter-specific max frame size limits. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	switch (hw->mac_type) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	case e1000_undefined ... e1000_82542_rev2_1:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
			e_err(probe, "Jumbo Frames not supported.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
			return -EINVAL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
		msleep(1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	/* e1000_down has a dependency on max_frame_size */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	hw->max_frame_size = max_frame;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	 * means we reserve 2 more, this pushes us to allocate from the next
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	 * larger slab size.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	 * i.e. RXBUFFER_2048 --> size-4096 slab
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	 *  fragmented skbs */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	if (max_frame <= E1000_RXBUFFER_2048)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
		adapter->rx_buffer_len = PAGE_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	/* adjust allocation if LPE protects us, and we aren't using SBP */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	if (!hw->tbi_compatibility_on &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	pr_info("%s changing MTU from %d to %d\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		netdev->name, netdev->mtu, new_mtu);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	netdev->mtu = new_mtu;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
		e1000_up(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
		e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	clear_bit(__E1000_RESETTING, &adapter->flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
 * e1000_update_stats - Update the board statistics counters
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
void e1000_update_stats(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	unsigned long flags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	u16 phy_tmp;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	 * Prevent stats update while adapter is being reset, or if the pci
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	 * connection is down.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	if (adapter->link_speed == 0)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	if (pci_channel_offline(pdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	spin_lock_irqsave(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	/* these counters are modified from e1000_tbi_adjust_stats,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	 * called from the interrupt context, so they must only
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	 * be written while holding adapter->stats_lock
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	adapter->stats.crcerrs += er32(CRCERRS);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	adapter->stats.gprc += er32(GPRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	adapter->stats.gorcl += er32(GORCL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->stats.gorch += er32(GORCH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	adapter->stats.bprc += er32(BPRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	adapter->stats.mprc += er32(MPRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	adapter->stats.roc += er32(ROC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	adapter->stats.prc64 += er32(PRC64);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	adapter->stats.prc127 += er32(PRC127);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	adapter->stats.prc255 += er32(PRC255);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	adapter->stats.prc511 += er32(PRC511);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	adapter->stats.prc1023 += er32(PRC1023);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	adapter->stats.prc1522 += er32(PRC1522);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	adapter->stats.symerrs += er32(SYMERRS);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	adapter->stats.mpc += er32(MPC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	adapter->stats.scc += er32(SCC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	adapter->stats.ecol += er32(ECOL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	adapter->stats.mcc += er32(MCC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	adapter->stats.latecol += er32(LATECOL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	adapter->stats.dc += er32(DC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	adapter->stats.sec += er32(SEC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	adapter->stats.rlec += er32(RLEC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	adapter->stats.xonrxc += er32(XONRXC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	adapter->stats.xontxc += er32(XONTXC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	adapter->stats.xoffrxc += er32(XOFFRXC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	adapter->stats.xofftxc += er32(XOFFTXC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	adapter->stats.fcruc += er32(FCRUC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	adapter->stats.gptc += er32(GPTC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	adapter->stats.gotcl += er32(GOTCL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	adapter->stats.gotch += er32(GOTCH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	adapter->stats.rnbc += er32(RNBC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	adapter->stats.ruc += er32(RUC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	adapter->stats.rfc += er32(RFC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	adapter->stats.rjc += er32(RJC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	adapter->stats.torl += er32(TORL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	adapter->stats.torh += er32(TORH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	adapter->stats.totl += er32(TOTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	adapter->stats.toth += er32(TOTH);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	adapter->stats.tpr += er32(TPR);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	adapter->stats.ptc64 += er32(PTC64);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	adapter->stats.ptc127 += er32(PTC127);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	adapter->stats.ptc255 += er32(PTC255);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	adapter->stats.ptc511 += er32(PTC511);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	adapter->stats.ptc1023 += er32(PTC1023);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	adapter->stats.ptc1522 += er32(PTC1522);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	adapter->stats.mptc += er32(MPTC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	adapter->stats.bptc += er32(BPTC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	/* used for adaptive IFS */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	hw->tx_packet_delta = er32(TPT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	adapter->stats.tpt += hw->tx_packet_delta;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	hw->collision_delta = er32(COLC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	adapter->stats.colc += hw->collision_delta;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	if (hw->mac_type >= e1000_82543) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		adapter->stats.algnerrc += er32(ALGNERRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		adapter->stats.rxerrc += er32(RXERRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		adapter->stats.tncrs += er32(TNCRS);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		adapter->stats.cexterr += er32(CEXTERR);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		adapter->stats.tsctc += er32(TSCTC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		adapter->stats.tsctfc += er32(TSCTFC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	/* Fill out the OS statistics structure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	netdev->stats.multicast = adapter->stats.mprc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	netdev->stats.collisions = adapter->stats.colc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	/* Rx Errors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	/* RLEC on some newer hardware can be incorrect so build
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	* our own version based on RUC and ROC */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	netdev->stats.rx_errors = adapter->stats.rxerrc +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		adapter->stats.crcerrs + adapter->stats.algnerrc +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		adapter->stats.ruc + adapter->stats.roc +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		adapter->stats.cexterr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	/* Tx Errors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	netdev->stats.tx_errors = adapter->stats.txerrc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	netdev->stats.tx_window_errors = adapter->stats.latecol;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	if (hw->bad_tx_carr_stats_fd &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	    adapter->link_duplex == FULL_DUPLEX) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
		netdev->stats.tx_carrier_errors = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		adapter->stats.tncrs = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	/* Tx Dropped needs to be maintained elsewhere */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	/* Phy Stats */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	if (hw->media_type == e1000_media_type_copper) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
		if ((adapter->link_speed == SPEED_1000) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
			adapter->phy_stats.idle_errors += phy_tmp;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		if ((hw->mac_type <= e1000_82546) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		   (hw->phy_type == e1000_phy_m88) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
			adapter->phy_stats.receive_errors += phy_tmp;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	/* Management Stats */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	if (hw->has_smbus) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
		adapter->stats.mgptc += er32(MGTPTC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
		adapter->stats.mgprc += er32(MGTPRC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
		adapter->stats.mgpdc += er32(MGTPDC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
 * e1000_intr - Interrupt Handler
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
 * @irq: interrupt number
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
 * @data: pointer to a network interface device structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
static irqreturn_t e1000_intr(int irq, void *data)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	struct net_device *netdev = data;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	u32 icr = er32(ICR);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
		return IRQ_NONE;  /* Not our interrupt */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		hw->get_link_status = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		/* guard against interrupt when we're going down */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	/* disable interrupts, without the synchronize_irq bit */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	ew32(IMC, ~0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	E1000_WRITE_FLUSH();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	if (likely(napi_schedule_prep(&adapter->napi))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		adapter->total_tx_bytes = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		adapter->total_tx_packets = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		adapter->total_rx_bytes = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		adapter->total_rx_packets = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		__napi_schedule(&adapter->napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		/* this really should not happen! if it does it is basically a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
		 * bug, but not a hard error, so enable ints and continue */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	return IRQ_HANDLED;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
 * e1000_clean - NAPI Rx polling callback
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
static int e1000_clean(struct napi_struct *napi, int budget)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	int tx_clean_complete = 0, work_done = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	if (!tx_clean_complete)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
		work_done = budget;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	/* If budget not fully consumed, exit the polling mode */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	if (work_done < budget) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		if (likely(adapter->itr_setting & 3))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
			e1000_set_itr(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		napi_complete(napi);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
			e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	return work_done;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
			       struct e1000_tx_ring *tx_ring)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	struct e1000_tx_desc *tx_desc, *eop_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	unsigned int i, eop;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	unsigned int count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	unsigned int total_tx_bytes=0, total_tx_packets=0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	i = tx_ring->next_to_clean;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	eop = tx_ring->buffer_info[i].next_to_watch;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	       (count < tx_ring->count)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		bool cleaned = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		rmb();	/* read buffer_info after eop_desc */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		for ( ; !cleaned; count++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
			tx_desc = E1000_TX_DESC(*tx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
			buffer_info = &tx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
			cleaned = (i == eop);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
			if (cleaned) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
				struct sk_buff *skb = buffer_info->skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
				unsigned int segs, bytecount;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
				segs = skb_shinfo(skb)->gso_segs ?: 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
				/* multiply data chunks by size of headers */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
				bytecount = ((segs - 1) * skb_headlen(skb)) +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
				            skb->len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
				total_tx_packets += segs;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
				total_tx_bytes += bytecount;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
			tx_desc->upper.data = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
			if (unlikely(++i == tx_ring->count)) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		eop = tx_ring->buffer_info[i].next_to_watch;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	tx_ring->next_to_clean = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
#define TX_WAKE_THRESHOLD 32
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
	if (unlikely(count && netif_carrier_ok(netdev) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		/* Make sure that anybody stopping the queue after this
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		 * sees the new next_to_clean.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		smp_mb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		if (netif_queue_stopped(netdev) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
			netif_wake_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
			++adapter->restart_queue;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	if (adapter->detect_tx_hung) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		/* Detect a transmit hang in hardware, this serializes the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		 * check with the clearing of time_stamp and movement of i */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		adapter->detect_tx_hung = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		if (tx_ring->buffer_info[eop].time_stamp &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		               (adapter->tx_timeout_factor * HZ)) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
			/* detected Tx unit hang */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
			e_err(drv, "Detected Tx Unit Hang\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
			      "  Tx Queue             <%lu>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
			      "  TDH                  <%x>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
			      "  TDT                  <%x>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
			      "  next_to_use          <%x>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
			      "  next_to_clean        <%x>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
			      "buffer_info[next_to_clean]\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
			      "  time_stamp           <%lx>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
			      "  next_to_watch        <%x>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
			      "  jiffies              <%lx>\n"
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
			      "  next_to_watch.status <%x>\n",
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
				(unsigned long)((tx_ring - adapter->tx_ring) /
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
					sizeof(struct e1000_tx_ring)),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
				readl(hw->hw_addr + tx_ring->tdh),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
				readl(hw->hw_addr + tx_ring->tdt),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
				tx_ring->next_to_use,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
				tx_ring->next_to_clean,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
				tx_ring->buffer_info[eop].time_stamp,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
				eop,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
				jiffies,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
				eop_desc->upper.fields.status);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
			netif_stop_queue(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	adapter->total_tx_bytes += total_tx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	adapter->total_tx_packets += total_tx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	netdev->stats.tx_bytes += total_tx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	netdev->stats.tx_packets += total_tx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	return count < tx_ring->count;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
 * e1000_rx_checksum - Receive Checksum Offload for 82543
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
 * @adapter:     board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
 * @status_err:  receive descriptor status and error fields
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
 * @csum:        receive descriptor csum field
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
 * @sk_buff:     socket buffer with received data
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
			      u32 csum, struct sk_buff *skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	u16 status = (u16)status_err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	u8 errors = (u8)(status_err >> 24);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	skb_checksum_none_assert(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	/* 82543 or newer only */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	if (unlikely(hw->mac_type < e1000_82543)) return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	/* Ignore Checksum bit is set */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	/* TCP/UDP checksum error bit is set */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
		/* let the stack verify checksum errors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		adapter->hw_csum_err++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	/* TCP/UDP Checksum has not been calculated */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	if (!(status & E1000_RXD_STAT_TCPCS))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	/* It must be a TCP or UDP packet with a valid checksum */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		/* TCP checksum is good */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		skb->ip_summed = CHECKSUM_UNNECESSARY;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	adapter->hw_csum_good++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
 * e1000_consume_page - helper function
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
                               u16 length)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	bi->page = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	skb->len += length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	skb->data_len += length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	skb->truesize += length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
 * e1000_receive_skb - helper function to handle rx indications
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
 * @status: descriptor status field as written by hardware
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
 * @skb: pointer to sk_buff to be indicated to stack
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
			      __le16 vlan, struct sk_buff *skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	skb->protocol = eth_type_trans(skb, adapter->netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
				 le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
				 skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
		napi_gro_receive(&adapter->napi, skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
 * @rx_ring: ring to clean
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
 * @work_done: amount of napi work completed this call
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
 * @work_to_do: max amount of work allowed for this call to do
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
 * the return value indicates whether actual cleaning was done, there
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
 * is no guarantee that everything was cleaned
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
				     struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
				     int *work_done, int work_to_do)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	struct e1000_rx_desc *rx_desc, *next_rxd;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	struct e1000_buffer *buffer_info, *next_buffer;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	unsigned long irq_flags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	u32 length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	int cleaned_count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	bool cleaned = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	unsigned int total_rx_bytes=0, total_rx_packets=0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	i = rx_ring->next_to_clean;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
	rx_desc = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	while (rx_desc->status & E1000_RXD_STAT_DD) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
		struct sk_buff *skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		u8 status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		if (*work_done >= work_to_do)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
		(*work_done)++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
		rmb(); /* read descriptor and rx_buffer_info after status DD */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
		status = rx_desc->status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
		skb = buffer_info->skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
		if (++i == rx_ring->count) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		next_rxd = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		prefetch(next_rxd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		next_buffer = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		cleaned = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		cleaned_count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		dma_unmap_page(&pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
			       buffer_info->length, DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		length = le16_to_cpu(rx_desc->length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		/* errors is only valid for DD + EOP descriptors */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
			u8 last_byte = *(skb->data + length - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
				       last_byte)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
				spin_lock_irqsave(&adapter->stats_lock,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
				                  irq_flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
				e1000_tbi_adjust_stats(hw, &adapter->stats,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
				                       length, skb->data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
				spin_unlock_irqrestore(&adapter->stats_lock,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
				                       irq_flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
				length--;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
			} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
				/* recycle both page and skb */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
				buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
				/* an error means any chain goes out the window
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
				 * too */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
				if (rx_ring->rx_skb_top)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
					dev_kfree_skb(rx_ring->rx_skb_top);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
				rx_ring->rx_skb_top = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
				goto next_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
#define rxtop rx_ring->rx_skb_top
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		if (!(status & E1000_RXD_STAT_EOP)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
			/* this descriptor is only the beginning (or middle) */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
			if (!rxtop) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
				/* this is the beginning of a chain */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
				rxtop = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
				                   0, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
			} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
				/* this is the middle of a chain */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
				skb_fill_page_desc(rxtop,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
				    skb_shinfo(rxtop)->nr_frags,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
				    buffer_info->page, 0, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
				/* re-use the skb, only consumed the page */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
				buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
			e1000_consume_page(buffer_info, rxtop, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
			goto next_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
			if (rxtop) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
				/* end of the chain */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
				skb_fill_page_desc(rxtop,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
				    skb_shinfo(rxtop)->nr_frags,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
				    buffer_info->page, 0, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
				/* re-use the current skb, we only consumed the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
				 * page */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
				buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
				skb = rxtop;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
				rxtop = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
				e1000_consume_page(buffer_info, skb, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
			} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
				/* no chain, got EOP, this buf is the packet
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
				 * copybreak to save the put_page/alloc_page */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
				if (length <= copybreak &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
				    skb_tailroom(skb) >= length) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
					u8 *vaddr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
					vaddr = kmap_atomic(buffer_info->page,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
					                    KM_SKB_DATA_SOFTIRQ);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
					memcpy(skb_tail_pointer(skb), vaddr, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
					kunmap_atomic(vaddr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
					              KM_SKB_DATA_SOFTIRQ);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
					/* re-use the page, so don't erase
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
					 * buffer_info->page */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
					skb_put(skb, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
				} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
					skb_fill_page_desc(skb, 0,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
					                   buffer_info->page, 0,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
				                           length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
					e1000_consume_page(buffer_info, skb,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
					                   length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
				}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		e1000_rx_checksum(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		                  (u32)(status) |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
		                  ((u32)(rx_desc->errors) << 24),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		                  le16_to_cpu(rx_desc->csum), skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		pskb_trim(skb, skb->len - 4);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		/* probably a little skewed due to removing CRC */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		total_rx_bytes += skb->len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		total_rx_packets++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		/* eth type trans needs skb->data to point to something */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
		if (!pskb_may_pull(skb, ETH_HLEN)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
			e_err(drv, "pskb_may_pull failed.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
			dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
			goto next_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
next_desc:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		rx_desc->status = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		/* return some buffers to hardware, one at a time is too slow */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
			cleaned_count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		/* use prefetched values */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		rx_desc = next_rxd;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		buffer_info = next_buffer;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
	rx_ring->next_to_clean = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
	if (cleaned_count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	adapter->total_rx_packets += total_rx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	adapter->total_rx_bytes += total_rx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	netdev->stats.rx_bytes += total_rx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	netdev->stats.rx_packets += total_rx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	return cleaned;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
 * this should improve performance for small packets with large amounts
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
 * of reassembly being done in the stack
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
static void e1000_check_copybreak(struct net_device *netdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
				 struct e1000_buffer *buffer_info,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
				 u32 length, struct sk_buff **skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	struct sk_buff *new_skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	if (length > copybreak)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
	if (!new_skb)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
				       (*skb)->data - NET_IP_ALIGN,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
				       length + NET_IP_ALIGN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	/* save the skb in buffer_info as good */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	buffer_info->skb = *skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	*skb = new_skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
 * @adapter: board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
 * @rx_ring: ring to clean
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
 * @work_done: amount of napi work completed this call
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
 * @work_to_do: max amount of work allowed for this call to do
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
			       struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
			       int *work_done, int work_to_do)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	struct e1000_rx_desc *rx_desc, *next_rxd;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	struct e1000_buffer *buffer_info, *next_buffer;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	unsigned long flags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	u32 length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	int cleaned_count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	bool cleaned = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	unsigned int total_rx_bytes=0, total_rx_packets=0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	i = rx_ring->next_to_clean;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	rx_desc = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	while (rx_desc->status & E1000_RXD_STAT_DD) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		struct sk_buff *skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		u8 status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
		if (*work_done >= work_to_do)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		(*work_done)++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		rmb(); /* read descriptor and rx_buffer_info after status DD */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		status = rx_desc->status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		skb = buffer_info->skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		prefetch(skb->data - NET_IP_ALIGN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		if (++i == rx_ring->count) i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		next_rxd = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
		prefetch(next_rxd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		next_buffer = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
		cleaned = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		cleaned_count++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
		dma_unmap_single(&pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
				 buffer_info->length, DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
		buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
		length = le16_to_cpu(rx_desc->length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
		/* !EOP means multiple descriptors were used to store a single
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		 * packet, if thats the case we need to toss it.  In fact, we
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
		 * to toss every packet with the EOP bit clear and the next
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
		 * frame that _does_ have the EOP bit set, as it is by
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
		 * definition only a frame fragment
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
			adapter->discarding = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		if (adapter->discarding) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
			/* All receives must fit into a single buffer */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
			e_dbg("Receive packet consumed multiple buffers\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			/* recycle */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			if (status & E1000_RXD_STAT_EOP)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
				adapter->discarding = false;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			goto next_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
			u8 last_byte = *(skb->data + length - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
				       last_byte)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
				spin_lock_irqsave(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
				e1000_tbi_adjust_stats(hw, &adapter->stats,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
				                       length, skb->data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
				spin_unlock_irqrestore(&adapter->stats_lock,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
				                       flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
				length--;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
			} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
				/* recycle */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
				buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
				goto next_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		/* adjust length to remove Ethernet CRC, this must be
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		 * done after the TBI_ACCEPT workaround above */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
		length -= 4;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
		/* probably a little skewed due to removing CRC */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		total_rx_bytes += length;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
		total_rx_packets++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		skb_put(skb, length);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
		/* Receive Checksum Offload */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		e1000_rx_checksum(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
				  (u32)(status) |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
				  ((u32)(rx_desc->errors) << 24),
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
				  le16_to_cpu(rx_desc->csum), skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
next_desc:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		rx_desc->status = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		/* return some buffers to hardware, one at a time is too slow */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
			cleaned_count = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		/* use prefetched values */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
		rx_desc = next_rxd;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		buffer_info = next_buffer;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
	rx_ring->next_to_clean = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	if (cleaned_count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	adapter->total_rx_packets += total_rx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	adapter->total_rx_bytes += total_rx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
	netdev->stats.rx_bytes += total_rx_bytes;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	netdev->stats.rx_packets += total_rx_packets;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
	return cleaned;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
 * @adapter: address of board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
 * @rx_ring: pointer to receive ring structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
 * @cleaned_count: number of buffers to allocate this pass
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
static void
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	struct e1000_rx_desc *rx_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
	struct sk_buff *skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	i = rx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
	buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	while (cleaned_count--) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		skb = buffer_info->skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
		if (skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			skb_trim(skb, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			goto check_page;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		if (unlikely(!skb)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			/* Better luck next round */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		/* Fix for errata 23, can't cross 64kB boundary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
			struct sk_buff *oldskb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
			e_err(rx_err, "skb align check failed: %u bytes at "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
			      "%p\n", bufsz, skb->data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
			/* Try again, without freeing the previous */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
			/* Failed allocation, critical failure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
			if (!skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
				dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
				adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
				/* give up */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
				dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
				dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
				break; /* while (cleaned_count--) */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
			/* Use new allocation */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
			dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
		buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		buffer_info->length = adapter->rx_buffer_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
check_page:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
		/* allocate a new page if necessary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		if (!buffer_info->page) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
			buffer_info->page = alloc_page(GFP_ATOMIC);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
			if (unlikely(!buffer_info->page)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
				adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
		if (!buffer_info->dma) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			buffer_info->dma = dma_map_page(&pdev->dev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
			                                buffer_info->page, 0,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
							buffer_info->length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
							DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
				put_page(buffer_info->page);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
				buffer_info->page = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
				buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
				buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
				adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
				break; /* while !buffer_info->skb */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		rx_desc = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
		if (unlikely(++i == rx_ring->count))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
			i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
		buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	if (likely(rx_ring->next_to_use != i)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
		rx_ring->next_to_use = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		if (unlikely(i-- == 0))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
			i = (rx_ring->count - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
		/* Force memory writes to complete before letting h/w
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		 * know there are new descriptors to fetch.  (Only
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		 * applicable for weak-ordered memory model archs,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
		 * such as IA-64). */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
		wmb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
 * @adapter: address of board private structure
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
				   struct e1000_rx_ring *rx_ring,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
				   int cleaned_count)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	struct net_device *netdev = adapter->netdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	struct pci_dev *pdev = adapter->pdev;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	struct e1000_rx_desc *rx_desc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	struct e1000_buffer *buffer_info;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
	struct sk_buff *skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	unsigned int i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	unsigned int bufsz = adapter->rx_buffer_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	i = rx_ring->next_to_use;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
	buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	while (cleaned_count--) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		skb = buffer_info->skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		if (skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
			skb_trim(skb, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
			goto map_skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		if (unlikely(!skb)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			/* Better luck next round */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
			adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
			break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		/* Fix for errata 23, can't cross 64kB boundary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
			struct sk_buff *oldskb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
			e_err(rx_err, "skb align check failed: %u bytes at "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
			      "%p\n", bufsz, skb->data);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			/* Try again, without freeing the previous */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			/* Failed allocation, critical failure */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			if (!skb) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
				dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
				adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
				/* give up */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
				dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
				dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
				adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
				break; /* while !buffer_info->skb */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
			/* Use new allocation */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
			dev_kfree_skb(oldskb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		buffer_info->skb = skb;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		buffer_info->length = adapter->rx_buffer_len;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
map_skb:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		buffer_info->dma = dma_map_single(&pdev->dev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
						  skb->data,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
						  buffer_info->length,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
						  DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
			dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
			adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
			break; /* while !buffer_info->skb */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
		 * XXX if it was allocated cleanly it will never map to a
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
		 * boundary crossing
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
		/* Fix for errata 23, can't cross 64kB boundary */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		if (!e1000_check_64k_bound(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
					(void *)(unsigned long)buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
					adapter->rx_buffer_len)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
			e_err(rx_err, "dma align check failed: %u bytes at "
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
			      "%p\n", adapter->rx_buffer_len,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
			      (void *)(unsigned long)buffer_info->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
			dev_kfree_skb(skb);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
			buffer_info->skb = NULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
			dma_unmap_single(&pdev->dev, buffer_info->dma,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
					 adapter->rx_buffer_len,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
					 DMA_FROM_DEVICE);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
			buffer_info->dma = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
			adapter->alloc_rx_buff_failed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
			break; /* while !buffer_info->skb */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
		rx_desc = E1000_RX_DESC(*rx_ring, i);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
		if (unlikely(++i == rx_ring->count))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
			i = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		buffer_info = &rx_ring->buffer_info[i];
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	if (likely(rx_ring->next_to_use != i)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
		rx_ring->next_to_use = i;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
		if (unlikely(i-- == 0))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			i = (rx_ring->count - 1);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		/* Force memory writes to complete before letting h/w
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		 * know there are new descriptors to fetch.  (Only
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		 * applicable for weak-ordered memory model archs,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
		 * such as IA-64). */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		wmb();
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		writel(i, hw->hw_addr + rx_ring->rdt);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
 * @adapter:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
static void e1000_smartspeed(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	u16 phy_status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	u16 phy_ctrl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	if (adapter->smartspeed == 0) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
		/* If Master/Slave config fault is asserted twice,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
		 * we assume back-to-back */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
					    phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
			adapter->smartspeed++;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
			if (!e1000_phy_setup_autoneg(hw) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
			   !e1000_read_phy_reg(hw, PHY_CTRL,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
				   	       &phy_ctrl)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
					     MII_CR_RESTART_AUTO_NEG);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
				e1000_write_phy_reg(hw, PHY_CTRL,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
						    phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
		/* If still no link, perhaps using 2/3 pair cable */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
		phy_ctrl |= CR_1000T_MS_ENABLE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		if (!e1000_phy_setup_autoneg(hw) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
				     MII_CR_RESTART_AUTO_NEG);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		adapter->smartspeed = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
 * e1000_ioctl -
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
 * @netdev:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
 * @ifreq:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
 * @cmd:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	switch (cmd) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	case SIOCGMIIPHY:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
	case SIOCGMIIREG:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
	case SIOCSMIIREG:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
		return e1000_mii_ioctl(netdev, ifr, cmd);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		return -EOPNOTSUPP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
 * e1000_mii_ioctl -
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
 * @netdev:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
 * @ifreq:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
 * @cmd:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
 **/
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
			   int cmd)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	struct mii_ioctl_data *data = if_mii(ifr);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	int retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
	u16 mii_reg;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	u16 spddplx;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	unsigned long flags;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	if (hw->media_type != e1000_media_type_copper)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		return -EOPNOTSUPP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	switch (cmd) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	case SIOCGMIIPHY:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
		data->phy_id = hw->phy_addr;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	case SIOCGMIIREG:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		spin_lock_irqsave(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
				   &data->val_out)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
			return -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	case SIOCSMIIREG:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
		if (data->reg_num & ~(0x1F))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
			return -EFAULT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
		mii_reg = data->val_in;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		spin_lock_irqsave(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		if (e1000_write_phy_reg(hw, data->reg_num,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
					mii_reg)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
			return -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
		if (hw->media_type == e1000_media_type_copper) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
			switch (data->reg_num) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
			case PHY_CTRL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
				if (mii_reg & MII_CR_POWER_DOWN)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
					break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
					hw->autoneg = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
					hw->autoneg_advertised = 0x2F;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
				} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
					if (mii_reg & 0x40)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
						spddplx = SPEED_1000;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
					else if (mii_reg & 0x2000)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
						spddplx = SPEED_100;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
					else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
						spddplx = SPEED_10;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
					spddplx += (mii_reg & 0x100)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
						   ? DUPLEX_FULL :
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
						   DUPLEX_HALF;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
					retval = e1000_set_spd_dplx(adapter,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
								    spddplx);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
					if (retval)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
						return retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
				}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
				if (netif_running(adapter->netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
					e1000_reinit_locked(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
				else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
					e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
			case M88E1000_PHY_SPEC_CTRL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
			case M88E1000_EXT_PHY_SPEC_CTRL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
				if (e1000_phy_reset(hw))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
					return -EIO;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
			switch (data->reg_num) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
			case PHY_CTRL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
				if (mii_reg & MII_CR_POWER_DOWN)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
					break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
				if (netif_running(adapter->netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
					e1000_reinit_locked(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
				else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
					e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
				break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
			}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
		return -EOPNOTSUPP;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	return E1000_SUCCESS;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
void e1000_pci_set_mwi(struct e1000_hw *hw)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
	struct e1000_adapter *adapter = hw->back;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	int ret_val = pci_set_mwi(adapter->pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	if (ret_val)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		e_err(probe, "Error in setting MWI\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
void e1000_pci_clear_mwi(struct e1000_hw *hw)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	struct e1000_adapter *adapter = hw->back;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	pci_clear_mwi(adapter->pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
	struct e1000_adapter *adapter = hw->back;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	return pcix_get_mmrbc(adapter->pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	struct e1000_adapter *adapter = hw->back;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	pcix_set_mmrbc(adapter->pdev, mmrbc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
	outl(value, port);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
static void e1000_vlan_rx_register(struct net_device *netdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
				   struct vlan_group *grp)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	u32 ctrl, rctl;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
	if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		e1000_irq_disable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	adapter->vlgrp = grp;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	if (grp) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		/* enable VLAN tag insert/strip */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		ctrl = er32(CTRL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		ctrl |= E1000_CTRL_VME;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		ew32(CTRL, ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
		/* enable VLAN receive filtering */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		rctl &= ~E1000_RCTL_CFIEN;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		if (!(netdev->flags & IFF_PROMISC))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
			rctl |= E1000_RCTL_VFE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
		ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		e1000_update_mng_vlan(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
		/* disable VLAN tag insert/strip */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
		ctrl = er32(CTRL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
		ctrl &= ~E1000_CTRL_VME;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		ew32(CTRL, ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		/* disable VLAN receive filtering */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		rctl &= ~E1000_RCTL_VFE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	u32 vfta, index;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	if ((hw->mng_cookie.status &
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	    (vid == adapter->mng_vlan_id))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	/* add VID to filter table */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	index = (vid >> 5) & 0x7F;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	vfta |= (1 << (vid & 0x1F));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	e1000_write_vfta(hw, index, vfta);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	u32 vfta, index;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		e1000_irq_disable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	if (!test_bit(__E1000_DOWN, &adapter->flags))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		e1000_irq_enable(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	/* remove VID from filter table */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	index = (vid >> 5) & 0x7F;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	vfta &= ~(1 << (vid & 0x1F));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	e1000_write_vfta(hw, index, vfta);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
static void e1000_restore_vlan(struct e1000_adapter *adapter)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	if (adapter->vlgrp) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		u16 vid;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		for (vid = 0; vid < VLAN_N_VID; vid++) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
			if (!vlan_group_get_device(adapter->vlgrp, vid))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
				continue;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	hw->autoneg = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	/* Fiber NICs only allow 1000 gbps Full duplex */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	if ((hw->media_type == e1000_media_type_fiber) &&
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		e_err(probe, "Unsupported Speed/Duplex configuration\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
		return -EINVAL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	switch (spddplx) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	case SPEED_10 + DUPLEX_HALF:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
		hw->forced_speed_duplex = e1000_10_half;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	case SPEED_10 + DUPLEX_FULL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		hw->forced_speed_duplex = e1000_10_full;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	case SPEED_100 + DUPLEX_HALF:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		hw->forced_speed_duplex = e1000_100_half;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	case SPEED_100 + DUPLEX_FULL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		hw->forced_speed_duplex = e1000_100_full;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	case SPEED_1000 + DUPLEX_FULL:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		hw->autoneg = 1;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		break;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	default:
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
		e_err(probe, "Unsupported Speed/Duplex configuration\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
		return -EINVAL;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	u32 ctrl, ctrl_ext, rctl, status;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	u32 wufc = adapter->wol;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
#ifdef CONFIG_PM
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	int retval = 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
	netif_device_detach(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	if (netif_running(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
#ifdef CONFIG_PM
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	retval = pci_save_state(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	if (retval)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
		return retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	status = er32(STATUS);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	if (status & E1000_STATUS_LU)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
		wufc &= ~E1000_WUFC_LNKC;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	if (wufc) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		e1000_setup_rctl(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
		e1000_set_rx_mode(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		/* turn on all-multi mode if wake on multicast is enabled */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		if (wufc & E1000_WUFC_MC) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
			rctl = er32(RCTL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
			rctl |= E1000_RCTL_MPE;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
			ew32(RCTL, rctl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		if (hw->mac_type >= e1000_82540) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
			ctrl = er32(CTRL);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			/* advertise wake from D3Cold */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			#define E1000_CTRL_ADVD3WUC 0x00100000
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
			/* phy power management enable */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
			ctrl |= E1000_CTRL_ADVD3WUC |
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
				E1000_CTRL_EN_PHY_PWR_MGMT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
			ew32(CTRL, ctrl);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
		if (hw->media_type == e1000_media_type_fiber ||
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
		    hw->media_type == e1000_media_type_internal_serdes) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
			/* keep the laser running in D3 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			ctrl_ext = er32(CTRL_EXT);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
			ew32(CTRL_EXT, ctrl_ext);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
		ew32(WUC, E1000_WUC_PME_EN);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
		ew32(WUFC, wufc);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
		ew32(WUC, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		ew32(WUFC, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	e1000_release_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	*enable_wake = !!wufc;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
	/* make sure adapter isn't asleep if manageability is enabled */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	if (adapter->en_mng_pt)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		*enable_wake = true;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		e1000_free_irq(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	pci_disable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
#ifdef CONFIG_PM
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
	int retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	bool wake;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	retval = __e1000_shutdown(pdev, &wake);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	if (retval)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		return retval;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	if (wake) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		pci_prepare_to_sleep(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	} else {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
		pci_wake_from_d3(pdev, false);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		pci_set_power_state(pdev, PCI_D3hot);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
static int e1000_resume(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	u32 err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	pci_set_power_state(pdev, PCI_D0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
	pci_restore_state(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	pci_save_state(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	if (adapter->need_ioport)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
		err = pci_enable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
		err = pci_enable_device_mem(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
		pr_err("Cannot enable PCI device from suspend\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
		return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	pci_set_master(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	pci_enable_wake(pdev, PCI_D3hot, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	pci_enable_wake(pdev, PCI_D3cold, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	if (netif_running(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		err = e1000_request_irq(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		if (err)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
			return err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	e1000_power_up_phy(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	ew32(WUS, ~0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	e1000_init_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		e1000_up(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	netif_device_attach(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	return 0;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
static void e1000_shutdown(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	bool wake;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	__e1000_shutdown(pdev, &wake);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	if (system_state == SYSTEM_POWER_OFF) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		pci_wake_from_d3(pdev, wake);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
		pci_set_power_state(pdev, PCI_D3hot);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
#ifdef CONFIG_NET_POLL_CONTROLLER
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
/*
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
 * Polling 'interrupt' - used by things like netconsole to send skbs
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
 * without having to re-enable interrupts. It's not called while
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
 * the interrupt routine is executing.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
static void e1000_netpoll(struct net_device *netdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	disable_irq(adapter->pdev->irq);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	e1000_intr(adapter->pdev->irq, netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	enable_irq(adapter->pdev->irq);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
#endif
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
 * e1000_io_error_detected - called when PCI error is detected
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
 * @pdev: Pointer to PCI device
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
 * @state: The current pci connection state
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
 * This function is called after a PCI bus error affecting
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
 * this device has been detected.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
						pci_channel_state_t state)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
	netif_device_detach(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	if (state == pci_channel_io_perm_failure)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
		return PCI_ERS_RESULT_DISCONNECT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	if (netif_running(netdev))
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		e1000_down(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	pci_disable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	/* Request a slot slot reset. */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	return PCI_ERS_RESULT_NEED_RESET;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
 * e1000_io_slot_reset - called after the pci bus has been reset.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
 * @pdev: Pointer to PCI device
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
 * Restart the card from scratch, as if from a cold-boot. Implementation
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
 * resembles the first-half of the e1000_resume routine.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	struct e1000_hw *hw = &adapter->hw;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	int err;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	if (adapter->need_ioport)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
		err = pci_enable_device(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	else
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		err = pci_enable_device_mem(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	if (err) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
		pr_err("Cannot re-enable PCI device after reset.\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
		return PCI_ERS_RESULT_DISCONNECT;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	pci_set_master(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
	pci_enable_wake(pdev, PCI_D3hot, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	pci_enable_wake(pdev, PCI_D3cold, 0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
	e1000_reset(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	ew32(WUS, ~0);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	return PCI_ERS_RESULT_RECOVERED;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
/**
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
 * e1000_io_resume - called when traffic can start flowing again.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
 * @pdev: Pointer to PCI device
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
 *
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
 * This callback is called when the error recovery driver tells us that
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
 * its OK to resume normal operation. Implementation resembles the
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
 * second-half of the e1000_resume routine.
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
 */
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
static void e1000_io_resume(struct pci_dev *pdev)
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
{
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	struct net_device *netdev = pci_get_drvdata(pdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	struct e1000_adapter *adapter = netdev_priv(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	e1000_init_manageability(adapter);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	if (netif_running(netdev)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		if (e1000_up(adapter)) {
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
			pr_info("can't bring device back up after reset\n");
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
			return;
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
		}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	netif_device_attach(netdev);
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
}
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
312ab8ed8284 Added e1000 driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
/* e1000_main.c */