devices/e1000/e1000_main-2.6.35-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2287 fda70486f179
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2287
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k6-NAPI"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
				    struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static int e1000_set_mac(struct net_device *netdev, void *p);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr(int irq, void *data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
				     struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
				     int *work_done, int work_to_do);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
				   struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				   int cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
					 struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
					 int cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			   int cmd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_tx_timeout(struct net_device *dev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_reset_task(struct work_struct *work);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_smartspeed(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
                                       struct sk_buff *skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_restore_vlan(struct e1000_adapter *adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_PM
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static int e1000_resume(struct pci_dev *pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_shutdown(struct pci_dev *pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
#ifdef CONFIG_NET_POLL_CONTROLLER
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
/* for netdump / net console */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_netpoll (struct net_device *netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#define COPYBREAK_DEFAULT 256
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
module_param(copybreak, uint, 0644);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
MODULE_PARM_DESC(copybreak,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	"Maximum size of packet that is copied to a new buffer on receive");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
                     pci_channel_state_t state);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_io_resume(struct pci_dev *pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static struct pci_error_handlers e1000_err_handler = {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	.error_detected = e1000_io_error_detected,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	.slot_reset = e1000_io_slot_reset,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.resume = e1000_io_resume,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
};
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static struct pci_driver e1000_driver = {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.name     = e1000_driver_name,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	.id_table = e1000_pci_tbl,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.probe    = e1000_probe,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.remove   = __devexit_p(e1000_remove),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#ifdef CONFIG_PM
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	/* Power Managment Hooks */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.suspend  = e1000_suspend,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.resume   = e1000_resume,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.shutdown = e1000_shutdown,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.err_handler = &e1000_err_handler
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
};
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
MODULE_LICENSE("GPL");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
MODULE_VERSION(DRV_VERSION);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
module_param(debug, int, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 * e1000_get_hw_dev - return device
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
 * used by hardware layer to print debugging information
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	struct e1000_adapter *adapter = hw->back;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	return adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
 * e1000_init_module - Driver Registration Routine
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
 * e1000_init_module is the first routine called when the driver is
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
 * loaded. All it does is register with the PCI subsystem.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
static int __init e1000_init_module(void)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	int ret;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	pr_info("%s\n", e1000_copyright);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	ret = pci_register_driver(&e1000_driver);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	if (copybreak != COPYBREAK_DEFAULT) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		if (copybreak == 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
			pr_info("copybreak disabled\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
		else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
			pr_info("copybreak enabled for "
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
				   "packets <= %u bytes\n", copybreak);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	return ret;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
module_init(e1000_init_module);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
 * e1000_exit_module - Driver Exit Cleanup Routine
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 * e1000_exit_module is called just before the driver is removed
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 * from memory.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
static void __exit e1000_exit_module(void)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	pci_unregister_driver(&e1000_driver);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
module_exit(e1000_exit_module);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
static int e1000_request_irq(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	irq_handler_t handler = e1000_intr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	int irq_flags = IRQF_SHARED;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	int err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	                  netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		e_err("Unable to allocate interrupt Error: %d\n", err);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
static void e1000_free_irq(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	free_irq(adapter->pdev->irq, netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
 * e1000_irq_disable - Mask off interrupt generation on the NIC
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
static void e1000_irq_disable(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	ew32(IMC, ~0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	synchronize_irq(adapter->pdev->irq);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 * e1000_irq_enable - Enable default interrupt generation settings
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
static void e1000_irq_enable(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	ew32(IMS, IMS_ENABLE_MASK);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	u16 vid = hw->mng_cookie.vlan_id;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	u16 old_vid = adapter->mng_vlan_id;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	if (adapter->vlgrp) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
			if (hw->mng_cookie.status &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
				e1000_vlan_rx_add_vid(netdev, vid);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
				adapter->mng_vlan_id = vid;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
			} else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
					(vid != old_vid) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
				e1000_vlan_rx_kill_vid(netdev, old_vid);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		} else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
			adapter->mng_vlan_id = vid;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
static void e1000_init_manageability(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	if (adapter->en_mng_pt) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		u32 manc = er32(MANC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		/* disable hardware interception of ARP */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		manc &= ~(E1000_MANC_ARP_EN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		ew32(MANC, manc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
static void e1000_release_manageability(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	if (adapter->en_mng_pt) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		u32 manc = er32(MANC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		/* re-enable hardware interception of ARP */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		manc |= E1000_MANC_ARP_EN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		ew32(MANC, manc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
 * e1000_configure - configure the hardware for RX and TX
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
 * @adapter = private board structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
static void e1000_configure(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	e1000_set_rx_mode(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	e1000_restore_vlan(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	e1000_init_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	e1000_configure_tx(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	e1000_setup_rctl(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	e1000_configure_rx(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	/* call E1000_DESC_UNUSED which always leaves
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	 * at least 1 descriptor unused to make sure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	 * next_to_use != next_to_clean */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	for (i = 0; i < adapter->num_rx_queues; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		adapter->alloc_rx_buf(adapter, ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		                      E1000_DESC_UNUSED(ring));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
int e1000_up(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	/* hardware has been reset, we need to reload some things */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	e1000_configure(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	clear_bit(__E1000_DOWN, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	napi_enable(&adapter->napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	netif_wake_queue(adapter->netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	/* fire a link change interrupt to start the watchdog */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	ew32(ICS, E1000_ICS_LSC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
 * e1000_power_up_phy - restore link in case the phy was powered down
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
 * @adapter: address of board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 * The phy may be powered down to save power and turn off link when the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
 * driver is unloaded and wake on lan is not enabled (among others)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 * *** this routine MUST be followed by a call to e1000_reset ***
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
void e1000_power_up_phy(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	u16 mii_reg = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	/* Just clear the power down bit to wake the phy back up */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	if (hw->media_type == e1000_media_type_copper) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		/* according to the manual, the phy will retain its
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		 * settings across a power-down/up cycle */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		mii_reg &= ~MII_CR_POWER_DOWN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
static void e1000_power_down_phy(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* Power down the PHY so no link is implied when interface is down *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * The PHY cannot be powered down if any of the following is true *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 * (a) WoL is enabled
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	 * (b) AMT is active
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	 * (c) SoL/IDER session is active */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	   hw->media_type == e1000_media_type_copper) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		u16 mii_reg = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
		case e1000_82540:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		case e1000_82545:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		case e1000_82545_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		case e1000_82546:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		case e1000_82546_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		case e1000_82541:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		case e1000_82541_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		case e1000_82547:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		case e1000_82547_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
				goto out;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
			goto out;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		mii_reg |= MII_CR_POWER_DOWN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		mdelay(1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
out:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
void e1000_down(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	u32 rctl, tctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	/* signal that we're down so the interrupt handler does not
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 * reschedule our watchdog timer */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	set_bit(__E1000_DOWN, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	/* disable receives in the hardware */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	/* flush and sleep below */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	netif_tx_disable(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	/* disable transmits in the hardware */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	tctl = er32(TCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	tctl &= ~E1000_TCTL_EN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	ew32(TCTL, tctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* flush both disables and wait for them to finish */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	msleep(10);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	napi_disable(&adapter->napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	e1000_irq_disable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	del_timer_sync(&adapter->tx_fifo_stall_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	del_timer_sync(&adapter->watchdog_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	del_timer_sync(&adapter->phy_info_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	adapter->link_speed = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	adapter->link_duplex = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	netif_carrier_off(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	e1000_clean_all_tx_rings(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	e1000_clean_all_rx_rings(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
void e1000_reinit_locked(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	WARN_ON(in_interrupt());
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		msleep(1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	e1000_down(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	e1000_up(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	clear_bit(__E1000_RESETTING, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
void e1000_reset(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	bool legacy_pba_adjust = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	u16 hwm;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	/* Repartition Pba for greater than 9k mtu
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	 * To take effect CTRL.RST is required.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	case e1000_82542_rev2_0:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	case e1000_82542_rev2_1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	case e1000_82543:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	case e1000_82544:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	case e1000_82540:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	case e1000_82541:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	case e1000_82541_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		legacy_pba_adjust = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		pba = E1000_PBA_48K;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	case e1000_82545:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	case e1000_82545_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	case e1000_82546:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	case e1000_82546_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		pba = E1000_PBA_48K;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	case e1000_82547:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	case e1000_82547_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		legacy_pba_adjust = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		pba = E1000_PBA_30K;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	case e1000_undefined:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	case e1000_num_macs:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	if (legacy_pba_adjust) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
			pba -= 8; /* allocate more FIFO for Tx */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		if (hw->mac_type == e1000_82547) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
			adapter->tx_fifo_head = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
			adapter->tx_fifo_size =
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
			atomic_set(&adapter->tx_fifo_stall, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		/* adjust PBA for jumbo frames */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		ew32(PBA, pba);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		/* To maintain wire speed transmits, the Tx FIFO should be
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		 * large enough to accommodate two full transmit packets,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		 * the Rx FIFO should be large enough to accommodate at least
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		 * one full receive packet and is similarly rounded up and
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		 * expressed in KB. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		pba = er32(PBA);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		/* upper 16 bits has Tx packet buffer allocation size in KB */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		tx_space = pba >> 16;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		/* lower 16 bits has Rx packet buffer allocation size in KB */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		pba &= 0xffff;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		 * the tx fifo also stores 16 bytes of information about the tx
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		 * but don't include ethernet FCS because hardware appends it
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		min_tx_space = (hw->max_frame_size +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		                sizeof(struct e1000_tx_desc) -
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		                ETH_FCS_LEN) * 2;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		min_tx_space = ALIGN(min_tx_space, 1024);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		min_tx_space >>= 10;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		/* software strips receive CRC, so leave room for it */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		min_rx_space = hw->max_frame_size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		min_rx_space = ALIGN(min_rx_space, 1024);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		min_rx_space >>= 10;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		/* If current Tx allocation is less than the min Tx FIFO size,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		 * and the min Tx FIFO size is less than the current Rx FIFO
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		 * allocation, take space away from current Rx allocation */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		if (tx_space < min_tx_space &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		    ((min_tx_space - tx_space) < pba)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			pba = pba - (min_tx_space - tx_space);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
			/* PCI/PCIx hardware has PBA alignment constraints */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
			case e1000_82545 ... e1000_82546_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
				pba &= ~(E1000_PBA_8K - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
			default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			/* if short on rx space, rx wins and must trump tx
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
			 * adjustment or use Early Receive if available */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
			if (pba < min_rx_space)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
				pba = min_rx_space;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	ew32(PBA, pba);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	 * flow control settings:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	 * The high water mark must be low enough to fit one full frame
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	 * (or the size used for early receive) above it in the Rx FIFO.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	 * Set it to the lower of:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	 * - 90% of the Rx FIFO size, and
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	 * - the full Rx FIFO size minus the early receive size (for parts
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	 * - the full Rx FIFO size minus one full frame
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	hwm = min(((pba << 10) * 9 / 10),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		  ((pba << 10) - hw->max_frame_size));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	hw->fc_low_water = hw->fc_high_water - 8;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	hw->fc_send_xon = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	hw->fc = hw->original_fc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	/* Allow time for pending master requests to run */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	e1000_reset_hw(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	if (hw->mac_type >= e1000_82544)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		ew32(WUC, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	if (e1000_init_hw(hw))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		e_err("Hardware Error\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	e1000_update_mng_vlan(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	if (hw->mac_type >= e1000_82544 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	    hw->autoneg == 1 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		u32 ctrl = er32(CTRL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		/* clear phy power management bit if we are in gig only mode,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		 * which if enabled will attempt negotiation to 100Mb, which
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		 * can cause a loss of link at power off or driver unload */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		ctrl &= ~E1000_CTRL_SWDPIN3;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		ew32(CTRL, ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	e1000_reset_adaptive(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	e1000_phy_get_info(hw, &adapter->phy_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	e1000_release_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 *  Dump the eeprom for users having checksum issues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	struct ethtool_eeprom eeprom;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	const struct ethtool_ops *ops = netdev->ethtool_ops;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	u8 *data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	u16 csum_old, csum_new = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	eeprom.len = ops->get_eeprom_len(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	eeprom.offset = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	data = kmalloc(eeprom.len, GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	if (!data) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		pr_err("Unable to allocate memory to dump EEPROM data\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	ops->get_eeprom(netdev, &eeprom, data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		csum_new += data[i] + (data[i + 1] << 8);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	csum_new = EEPROM_SUM - csum_new;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	pr_err("/*********************/\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	pr_err("Calculated              : 0x%04x\n", csum_new);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	pr_err("Offset    Values\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	pr_err("========  ======\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	pr_err("Include this output when contacting your support provider.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	pr_err("This is not a software error! Something bad happened to\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	pr_err("result in further problems, possibly loss of data,\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	pr_err("corruption or system hangs!\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	pr_err("which is invalid and requires you to set the proper MAC\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	pr_err("address manually before continuing to enable this network\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	pr_err("device. Please inspect the EEPROM dump and report the\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	pr_err("/*********************/\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	kfree(data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
 * @pdev: PCI device information struct
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
 * Return true if an adapter needs ioport resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
static int e1000_is_need_ioport(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	switch (pdev->device) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	case E1000_DEV_ID_82540EM:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	case E1000_DEV_ID_82540EM_LOM:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	case E1000_DEV_ID_82540EP:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	case E1000_DEV_ID_82540EP_LOM:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	case E1000_DEV_ID_82540EP_LP:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	case E1000_DEV_ID_82541EI:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	case E1000_DEV_ID_82541EI_MOBILE:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	case E1000_DEV_ID_82541ER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	case E1000_DEV_ID_82541ER_LOM:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	case E1000_DEV_ID_82541GI:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	case E1000_DEV_ID_82541GI_LF:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	case E1000_DEV_ID_82541GI_MOBILE:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	case E1000_DEV_ID_82544EI_COPPER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	case E1000_DEV_ID_82544EI_FIBER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	case E1000_DEV_ID_82544GC_COPPER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	case E1000_DEV_ID_82544GC_LOM:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	case E1000_DEV_ID_82545EM_COPPER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	case E1000_DEV_ID_82545EM_FIBER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	case E1000_DEV_ID_82546EB_COPPER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	case E1000_DEV_ID_82546EB_FIBER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		return true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		return false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
static const struct net_device_ops e1000_netdev_ops = {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	.ndo_open		= e1000_open,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	.ndo_stop		= e1000_close,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	.ndo_start_xmit		= e1000_xmit_frame,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	.ndo_get_stats		= e1000_get_stats,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	.ndo_set_rx_mode	= e1000_set_rx_mode,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	.ndo_set_mac_address	= e1000_set_mac,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	.ndo_tx_timeout 	= e1000_tx_timeout,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	.ndo_change_mtu		= e1000_change_mtu,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	.ndo_do_ioctl		= e1000_ioctl,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	.ndo_validate_addr	= eth_validate_addr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
#ifdef CONFIG_NET_POLL_CONTROLLER
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	.ndo_poll_controller	= e1000_netpoll,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
};
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
 * e1000_probe - Device Initialization Routine
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
 * @pdev: PCI device information struct
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
 * @ent: entry in e1000_pci_tbl
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
 * Returns 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
 * e1000_probe initializes an adapter identified by a pci_dev structure.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 * The OS initialization, configuring of the adapter private structure,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 * and a hardware reset occur.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
static int __devinit e1000_probe(struct pci_dev *pdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
				 const struct pci_device_id *ent)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	struct net_device *netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	struct e1000_adapter *adapter;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct e1000_hw *hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	static int cards_found = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	int i, err, pci_using_dac;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	u16 eeprom_data = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	int bars, need_ioport;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	/* do not allocate ioport bars when not needed */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	need_ioport = e1000_is_need_ioport(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	if (need_ioport) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		err = pci_enable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		err = pci_enable_device_mem(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	    !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		pci_using_dac = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			err = dma_set_coherent_mask(&pdev->dev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
						    DMA_BIT_MASK(32));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
			if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
				pr_err("No usable DMA config, aborting\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
				goto err_dma;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		pci_using_dac = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		goto err_pci_reg;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	pci_set_master(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	err = pci_save_state(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		goto err_alloc_etherdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	err = -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	if (!netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		goto err_alloc_etherdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	SET_NETDEV_DEV(netdev, &pdev->dev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	pci_set_drvdata(pdev, netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	adapter->netdev = netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	adapter->pdev = pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	adapter->msg_enable = (1 << debug) - 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	adapter->bars = bars;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	adapter->need_ioport = need_ioport;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	hw->back = adapter;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	err = -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	if (!hw->hw_addr)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		goto err_ioremap;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	if (adapter->need_ioport) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		for (i = BAR_1; i <= BAR_5; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
			if (pci_resource_len(pdev, i) == 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
				continue;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
				hw->io_base = pci_resource_start(pdev, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	netdev->netdev_ops = &e1000_netdev_ops;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	e1000_set_ethtool_ops(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	netdev->watchdog_timeo = 5 * HZ;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	adapter->bd_number = cards_found;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	/* setup the private structure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	err = e1000_sw_init(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		goto err_sw_init;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	err = -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	if (hw->mac_type >= e1000_82543) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		netdev->features = NETIF_F_SG |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
				   NETIF_F_HW_CSUM |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
				   NETIF_F_HW_VLAN_TX |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
				   NETIF_F_HW_VLAN_RX |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
				   NETIF_F_HW_VLAN_FILTER;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	if ((hw->mac_type >= e1000_82544) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	   (hw->mac_type != e1000_82547))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		netdev->features |= NETIF_F_TSO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	if (pci_using_dac)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
		netdev->features |= NETIF_F_HIGHDMA;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	netdev->vlan_features |= NETIF_F_TSO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	netdev->vlan_features |= NETIF_F_HW_CSUM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	netdev->vlan_features |= NETIF_F_SG;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	/* initialize eeprom parameters */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	if (e1000_init_eeprom_params(hw)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		e_err("EEPROM initialization failed\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		goto err_eeprom;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	/* before reading the EEPROM, reset the controller to
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	 * put the device in a known good starting state */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	e1000_reset_hw(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	/* make sure the EEPROM is good */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	if (e1000_validate_eeprom_checksum(hw) < 0) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		e_err("The EEPROM Checksum Is Not Valid\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		e1000_dump_eeprom(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		 * set MAC address to all zeroes to invalidate and temporary
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		 * disable this device for the user. This blocks regular
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		 * traffic while still permitting ethtool ioctls from reaching
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		 * the hardware as well as allowing the user to run the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		 * interface after manually setting a hw addr using
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		 * `ip set address`
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		memset(hw->mac_addr, 0, netdev->addr_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
		/* copy the MAC address out of the EEPROM */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		if (e1000_read_mac_addr(hw))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
			e_err("EEPROM Read Error\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	/* don't block initalization here due to bad MAC address */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	if (!is_valid_ether_addr(netdev->perm_addr))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		e_err("Invalid MAC Address\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	e1000_get_bus_info(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	init_timer(&adapter->tx_fifo_stall_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	init_timer(&adapter->watchdog_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	adapter->watchdog_timer.function = &e1000_watchdog;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	adapter->watchdog_timer.data = (unsigned long) adapter;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	init_timer(&adapter->phy_info_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	adapter->phy_info_timer.function = &e1000_update_phy_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	adapter->phy_info_timer.data = (unsigned long)adapter;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	e1000_check_options(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	/* Initial Wake on LAN setting
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	 * If APM wake is enabled in the EEPROM,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	 * enable the ACPI Magic Packet filter
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	case e1000_82542_rev2_0:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	case e1000_82542_rev2_1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	case e1000_82543:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	case e1000_82544:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		e1000_read_eeprom(hw,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	case e1000_82546:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	case e1000_82546_rev_3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
			e1000_read_eeprom(hw,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		/* Fall Through */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		e1000_read_eeprom(hw,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	if (eeprom_data & eeprom_apme_mask)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		adapter->eeprom_wol |= E1000_WUFC_MAG;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	/* now that we have the eeprom settings, apply the special cases
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	 * where the eeprom may be wrong or the board simply won't support
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	 * wake on lan on a particular port */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	switch (pdev->device) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	case E1000_DEV_ID_82546GB_PCIE:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		adapter->eeprom_wol = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	case E1000_DEV_ID_82546EB_FIBER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	case E1000_DEV_ID_82546GB_FIBER:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		/* Wake events only supported on port A for dual fiber
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		 * regardless of eeprom setting */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			adapter->eeprom_wol = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		/* if quad port adapter, disable WoL on all but port A */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		if (global_quad_port_a != 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
			adapter->eeprom_wol = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
			adapter->quad_port_a = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		/* Reset for multiple quad port adapters */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		if (++global_quad_port_a == 4)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
			global_quad_port_a = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	/* initialize the wol settings based on the eeprom settings */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	adapter->wol = adapter->eeprom_wol;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	/* reset the hardware with the new settings */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	strcpy(netdev->name, "eth%d");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	err = register_netdev(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		goto err_register;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	/* print bus type/speed/width info */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	e_info("(PCI%s:%dMHz:%d-bit) %pM\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	       netdev->dev_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	/* carrier off reporting is important to ethtool even BEFORE open */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	netif_carrier_off(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	e_info("Intel(R) PRO/1000 Network Connection\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	cards_found++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
err_register:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
err_eeprom:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	e1000_phy_hw_reset(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	if (hw->flash_address)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		iounmap(hw->flash_address);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	kfree(adapter->tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	kfree(adapter->rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
err_sw_init:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	iounmap(hw->hw_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
err_ioremap:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	free_netdev(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
err_alloc_etherdev:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	pci_release_selected_regions(pdev, bars);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
err_pci_reg:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
err_dma:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	pci_disable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
 * e1000_remove - Device Removal Routine
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
 * @pdev: PCI device information struct
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
 * e1000_remove is called by the PCI subsystem to alert the driver
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
 * that it should release a PCI device.  The could be caused by a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
 * Hot-Plug event, or because the driver is going to be removed from
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
 * memory.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
static void __devexit e1000_remove(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	set_bit(__E1000_DOWN, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	del_timer_sync(&adapter->tx_fifo_stall_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	del_timer_sync(&adapter->watchdog_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	del_timer_sync(&adapter->phy_info_timer);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	cancel_work_sync(&adapter->reset_task);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	e1000_release_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	unregister_netdev(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	e1000_phy_hw_reset(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	kfree(adapter->tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	kfree(adapter->rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	iounmap(hw->hw_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	if (hw->flash_address)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		iounmap(hw->flash_address);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	pci_release_selected_regions(pdev, adapter->bars);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	free_netdev(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	pci_disable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
 * @adapter: board private structure to initialize
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
 * e1000_sw_init initializes the Adapter private data structure.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
 * Fields are initialized based on PCI device information and
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
 * OS network device settings (MTU size).
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	/* PCI config space info */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	hw->vendor_id = pdev->vendor;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	hw->device_id = pdev->device;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	hw->subsystem_id = pdev->subsystem_device;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	hw->revision_id = pdev->revision;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	hw->max_frame_size = netdev->mtu +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	/* identify the MAC */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	if (e1000_set_mac_type(hw)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		e_err("Unknown MAC Type\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		return -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	case e1000_82541:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	case e1000_82547:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	case e1000_82541_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	case e1000_82547_rev_2:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		hw->phy_init_script = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	e1000_set_media_type(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	hw->wait_autoneg_complete = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	hw->tbi_compatibility_en = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	hw->adaptive_ifs = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	/* Copper options */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	if (hw->media_type == e1000_media_type_copper) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		hw->mdix = AUTO_ALL_MODES;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		hw->disable_polarity_correction = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		hw->master_slave = E1000_MASTER_SLAVE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	adapter->num_tx_queues = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	adapter->num_rx_queues = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	if (e1000_alloc_queues(adapter)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		e_err("Unable to allocate memory for queues\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	/* Explicitly disable IRQ since the NIC can be in any state. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	e1000_irq_disable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	spin_lock_init(&adapter->stats_lock);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	set_bit(__E1000_DOWN, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 * e1000_alloc_queues - Allocate memory for all rings
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
 * @adapter: board private structure to initialize
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
 * We allocate one ring per queue at run-time since we don't know the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
 * number of queues at compile-time.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	if (!adapter->tx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	if (!adapter->rx_ring) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		kfree(adapter->tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	return E1000_SUCCESS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 * e1000_open - Called when a network interface is made active
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
 * Returns 0 on success, negative value on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
 * The open entry point is called when a network interface is made
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
 * active by the system (IFF_UP).  At this point all resources needed
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
 * for transmit and receive operations are allocated, the interrupt
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
 * handler is registered with the OS, the watchdog timer is started,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
 * and the stack is notified that the interface is ready.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
static int e1000_open(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	int err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	/* disallow open during test */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	if (test_bit(__E1000_TESTING, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		return -EBUSY;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	netif_carrier_off(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	/* allocate transmit descriptors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	err = e1000_setup_all_tx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		goto err_setup_tx;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	/* allocate receive descriptors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	err = e1000_setup_all_rx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		goto err_setup_rx;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	e1000_power_up_phy(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	if ((hw->mng_cookie.status &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		e1000_update_mng_vlan(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	/* before we allocate an interrupt, we must be ready to handle it.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	 * as soon as we call pci_request_irq, so we have to setup our
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 * clean_rx handler before we do so.  */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	e1000_configure(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	err = e1000_request_irq(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		goto err_req_irq;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	/* From here on the code is the same as e1000_up() */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	clear_bit(__E1000_DOWN, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	napi_enable(&adapter->napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	netif_start_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	/* fire a link status change interrupt to start the watchdog */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	ew32(ICS, E1000_ICS_LSC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	return E1000_SUCCESS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
err_req_irq:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	e1000_power_down_phy(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	e1000_free_all_rx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
err_setup_rx:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	e1000_free_all_tx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
err_setup_tx:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 * e1000_close - Disables a network interface
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 * Returns 0, this is not allowed to fail
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * The close entry point is called when an interface is de-activated
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 * by the OS.  The hardware is still under the drivers control, but
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 * needs to be disabled.  A global MAC reset is issued to stop the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 * hardware, and all transmit and receive resources are freed.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
static int e1000_close(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	e1000_down(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	e1000_power_down_phy(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	e1000_free_irq(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	e1000_free_all_tx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	e1000_free_all_rx_resources(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	/* kill manageability vlan ID if supported, but not if a vlan with
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	 * the same ID is registered on the host OS (let 8021q kill it) */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	if ((hw->mng_cookie.status &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	     !(adapter->vlgrp &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 * @adapter: address of board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 * @start: address of beginning of memory
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
 * @len: length of memory
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
				  unsigned long len)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	unsigned long begin = (unsigned long)start;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	unsigned long end = begin + len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	/* First rev 82545 and 82546 need to not allow any memory
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	 * write location to cross 64k boundary due to errata 23 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	if (hw->mac_type == e1000_82545 ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	    hw->mac_type == e1000_82546) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	return true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 * @txdr:    tx descriptor ring (for a specific queue) to setup
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 * Return 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
				    struct e1000_tx_ring *txdr)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	int size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	size = sizeof(struct e1000_buffer) * txdr->count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	txdr->buffer_info = vmalloc(size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	if (!txdr->buffer_info) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		e_err("Unable to allocate memory for the Tx descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	memset(txdr->buffer_info, 0, size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	/* round up to nearest 4K */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	txdr->size = ALIGN(txdr->size, 4096);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
					GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	if (!txdr->desc) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
setup_tx_desc_die:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		vfree(txdr->buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		e_err("Unable to allocate memory for the Tx descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	/* Fix for errata 23, can't cross 64kB boundary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		void *olddesc = txdr->desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		dma_addr_t olddma = txdr->dma;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		e_err("txdr align check failed: %u bytes at %p\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		      txdr->size, txdr->desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		/* Try again, without freeing the previous */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
						&txdr->dma, GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		/* Failed allocation, critical failure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
		if (!txdr->desc) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
			goto setup_tx_desc_die;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
			/* give up */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
					  txdr->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			e_err("Unable to allocate aligned memory "
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			      "for the transmit descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			vfree(txdr->buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
			return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			/* Free old allocation, new allocation was successful */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	memset(txdr->desc, 0, txdr->size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	txdr->next_to_use = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	txdr->next_to_clean = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 * 				  (Descriptors) for all queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
 * Return 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	int i, err = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	for (i = 0; i < adapter->num_tx_queues; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
			e_err("Allocation for Tx Queue %u failed\n", i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			for (i-- ; i >= 0; i--)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
				e1000_free_tx_resources(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
							&adapter->tx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
 * Configure the Tx unit of the MAC after a reset.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
static void e1000_configure_tx(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	u64 tdba;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	u32 tdlen, tctl, tipg;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	u32 ipgr1, ipgr2;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	/* Setup the HW Tx Head and Tail descriptor pointers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	switch (adapter->num_tx_queues) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	case 1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		tdba = adapter->tx_ring[0].dma;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		tdlen = adapter->tx_ring[0].count *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
			sizeof(struct e1000_tx_desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		ew32(TDLEN, tdlen);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		ew32(TDBAH, (tdba >> 32));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		ew32(TDT, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		ew32(TDH, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	/* Set the default values for the Tx Inter Packet Gap timer */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	if ((hw->media_type == e1000_media_type_fiber ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	     hw->media_type == e1000_media_type_internal_serdes))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	case e1000_82542_rev2_0:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	case e1000_82542_rev2_1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		tipg = DEFAULT_82542_TIPG_IPGT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	ew32(TIPG, tipg);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	/* Set the Tx Interrupt Delay register */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	ew32(TIDV, adapter->tx_int_delay);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	if (hw->mac_type >= e1000_82540)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		ew32(TADV, adapter->tx_abs_int_delay);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	/* Program the Transmit Control Register */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	tctl = er32(TCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	tctl &= ~E1000_TCTL_CT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	e1000_config_collision_dist(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	/* Setup Transmit Descriptor Settings for eop descriptor */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	/* only set IDE if we are delaying interrupts using the timers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	if (adapter->tx_int_delay)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	if (hw->mac_type < e1000_82543)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	/* Cache if we're 82544 running in PCI-X because we'll
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	 * need this to apply a workaround later in the send path. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	if (hw->mac_type == e1000_82544 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	    hw->bus_type == e1000_bus_type_pcix)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		adapter->pcix_82544 = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	ew32(TCTL, tctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
 * Returns 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
				    struct e1000_rx_ring *rxdr)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	int size, desc_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	size = sizeof(struct e1000_buffer) * rxdr->count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	rxdr->buffer_info = vmalloc(size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	if (!rxdr->buffer_info) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		e_err("Unable to allocate memory for the Rx descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	memset(rxdr->buffer_info, 0, size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	desc_len = sizeof(struct e1000_rx_desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	/* Round up to nearest 4K */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	rxdr->size = rxdr->count * desc_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	rxdr->size = ALIGN(rxdr->size, 4096);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
					GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (!rxdr->desc) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		e_err("Unable to allocate memory for the Rx descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
setup_rx_desc_die:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		vfree(rxdr->buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		return -ENOMEM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	/* Fix for errata 23, can't cross 64kB boundary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		void *olddesc = rxdr->desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		dma_addr_t olddma = rxdr->dma;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		e_err("rxdr align check failed: %u bytes at %p\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		      rxdr->size, rxdr->desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		/* Try again, without freeing the previous */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
						&rxdr->dma, GFP_KERNEL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		/* Failed allocation, critical failure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		if (!rxdr->desc) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			e_err("Unable to allocate memory for the Rx descriptor "
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
			      "ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
			goto setup_rx_desc_die;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			/* give up */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
					  rxdr->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
			e_err("Unable to allocate aligned memory for the Rx "
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
			      "descriptor ring\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			goto setup_rx_desc_die;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
			/* Free old allocation, new allocation was successful */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
					  olddma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	memset(rxdr->desc, 0, rxdr->size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	rxdr->next_to_clean = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	rxdr->next_to_use = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	rxdr->rx_skb_top = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 * 				  (Descriptors) for all queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
 * Return 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	int i, err = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	for (i = 0; i < adapter->num_rx_queues; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			e_err("Allocation for Rx Queue %u failed\n", i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			for (i-- ; i >= 0; i--)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
				e1000_free_rx_resources(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
							&adapter->rx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
 * e1000_setup_rctl - configure the receive control registers
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
 * @adapter: Board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
static void e1000_setup_rctl(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	u32 rctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	if (hw->tbi_compatibility_on == 1)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		rctl |= E1000_RCTL_SBP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		rctl &= ~E1000_RCTL_SBP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
		rctl &= ~E1000_RCTL_LPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		rctl |= E1000_RCTL_LPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	/* Setup buffer sizes */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	rctl &= ~E1000_RCTL_SZ_4096;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	rctl |= E1000_RCTL_BSEX;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	switch (adapter->rx_buffer_len) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		case E1000_RXBUFFER_2048:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
			rctl |= E1000_RCTL_SZ_2048;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
			rctl &= ~E1000_RCTL_BSEX;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		case E1000_RXBUFFER_4096:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			rctl |= E1000_RCTL_SZ_4096;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		case E1000_RXBUFFER_8192:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			rctl |= E1000_RCTL_SZ_8192;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		case E1000_RXBUFFER_16384:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
			rctl |= E1000_RCTL_SZ_16384;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
 * Configure the Rx unit of the MAC after a reset.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
static void e1000_configure_rx(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	u64 rdba;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	u32 rdlen, rctl, rxcsum;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		rdlen = adapter->rx_ring[0].count *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		        sizeof(struct e1000_rx_desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		rdlen = adapter->rx_ring[0].count *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		        sizeof(struct e1000_rx_desc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		adapter->clean_rx = e1000_clean_rx_irq;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	/* disable receives while setting up the descriptors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	/* set the Receive Delay Timer Register */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	ew32(RDTR, adapter->rx_int_delay);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	if (hw->mac_type >= e1000_82540) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		ew32(RADV, adapter->rx_abs_int_delay);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		if (adapter->itr_setting != 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			ew32(ITR, 1000000000 / (adapter->itr * 256));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	 * the Base and Length of the Rx Descriptor Ring */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	switch (adapter->num_rx_queues) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	case 1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		rdba = adapter->rx_ring[0].dma;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		ew32(RDLEN, rdlen);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		ew32(RDBAH, (rdba >> 32));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		ew32(RDT, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		ew32(RDH, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	if (hw->mac_type >= e1000_82543) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		rxcsum = er32(RXCSUM);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		if (adapter->rx_csum)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
			rxcsum |= E1000_RXCSUM_TUOFL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
			/* don't need to clear IPPCSE as it defaults to 0 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			rxcsum &= ~E1000_RXCSUM_TUOFL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		ew32(RXCSUM, rxcsum);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	/* Enable Receives */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 * e1000_free_tx_resources - Free Tx Resources per Queue
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
 * @tx_ring: Tx descriptor ring for a specific queue
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
 * Free all transmit software resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
				    struct e1000_tx_ring *tx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	e1000_clean_tx_ring(adapter, tx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	vfree(tx_ring->buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	tx_ring->buffer_info = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
			  tx_ring->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	tx_ring->desc = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 * Free all transmit software resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	for (i = 0; i < adapter->num_tx_queues; i++)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
					     struct e1000_buffer *buffer_info)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	if (buffer_info->dma) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		if (buffer_info->mapped_as_page)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
				       buffer_info->length, DMA_TO_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
					 buffer_info->length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
					 DMA_TO_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	if (buffer_info->skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		dev_kfree_skb_any(buffer_info->skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	buffer_info->time_stamp = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	/* buffer_info must be completely set up in the transmit path */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
 * e1000_clean_tx_ring - Free Tx Buffers
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
 * @tx_ring: ring to be cleaned
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				struct e1000_tx_ring *tx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	unsigned long size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	/* Free all the Tx ring sk_buffs */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	for (i = 0; i < tx_ring->count; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	size = sizeof(struct e1000_buffer) * tx_ring->count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	memset(tx_ring->buffer_info, 0, size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	/* Zero out the descriptor ring */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	memset(tx_ring->desc, 0, tx_ring->size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	tx_ring->next_to_use = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	tx_ring->next_to_clean = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	tx_ring->last_tx_tso = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	writel(0, hw->hw_addr + tx_ring->tdh);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	writel(0, hw->hw_addr + tx_ring->tdt);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	for (i = 0; i < adapter->num_tx_queues; i++)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * e1000_free_rx_resources - Free Rx Resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 * @rx_ring: ring to clean the resources from
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 * Free all receive software resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
				    struct e1000_rx_ring *rx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	e1000_clean_rx_ring(adapter, rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	vfree(rx_ring->buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	rx_ring->buffer_info = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
			  rx_ring->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	rx_ring->desc = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * Free all receive software resources
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	for (i = 0; i < adapter->num_rx_queues; i++)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
 * @rx_ring: ring to free buffers from
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
				struct e1000_rx_ring *rx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	unsigned long size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	/* Free all the Rx ring sk_buffs */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	for (i = 0; i < rx_ring->count; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		if (buffer_info->dma &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		    adapter->clean_rx == e1000_clean_rx_irq) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			dma_unmap_single(&pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			                 buffer_info->length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
					 DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
		} else if (buffer_info->dma &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			dma_unmap_page(&pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
				       buffer_info->length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
				       DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		if (buffer_info->page) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
			put_page(buffer_info->page);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
			buffer_info->page = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		if (buffer_info->skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
			dev_kfree_skb(buffer_info->skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
			buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	/* there also may be some cached data from a chained receive */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	if (rx_ring->rx_skb_top) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		dev_kfree_skb(rx_ring->rx_skb_top);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		rx_ring->rx_skb_top = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	size = sizeof(struct e1000_buffer) * rx_ring->count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	memset(rx_ring->buffer_info, 0, size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	/* Zero out the descriptor ring */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	memset(rx_ring->desc, 0, rx_ring->size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	rx_ring->next_to_clean = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	rx_ring->next_to_use = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	writel(0, hw->hw_addr + rx_ring->rdh);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	writel(0, hw->hw_addr + rx_ring->rdt);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	for (i = 0; i < adapter->num_rx_queues; i++)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
 * and memory write and invalidate disabled for certain operations
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	u32 rctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	e1000_pci_clear_mwi(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	rctl |= E1000_RCTL_RST;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	mdelay(5);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		e1000_clean_all_rx_rings(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	u32 rctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	rctl &= ~E1000_RCTL_RST;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	mdelay(5);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		e1000_pci_set_mwi(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	if (netif_running(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		/* No need to loop, because 82542 supports only 1 queue */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		e1000_configure_rx(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
 * e1000_set_mac - Change the Ethernet Address of the NIC
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
 * @p: pointer to an address structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
 * Returns 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
static int e1000_set_mac(struct net_device *netdev, void *p)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	struct sockaddr *addr = p;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	if (!is_valid_ether_addr(addr->sa_data))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		return -EADDRNOTAVAIL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	/* 82542 2.0 needs to be in reset to write receive address registers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	if (hw->mac_type == e1000_82542_rev2_0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
		e1000_enter_82542_rst(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	e1000_rar_set(hw, hw->mac_addr, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	if (hw->mac_type == e1000_82542_rev2_0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		e1000_leave_82542_rst(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
 * The set_rx_mode entry point is called whenever the unicast or multicast
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
 * address lists or the network interface flags are updated. This routine is
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
 * responsible for configuring the hardware for proper unicast, multicast,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
 * promiscuous mode, and all-multi behavior.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
static void e1000_set_rx_mode(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	struct netdev_hw_addr *ha;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	bool use_uc = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	u32 rctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	u32 hash_value;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	int i, rar_entries = E1000_RAR_ENTRIES;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	if (!mcarray) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		e_err("memory allocation failed\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	/* Check for Promiscuous and All Multicast modes */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	if (netdev->flags & IFF_PROMISC) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		rctl &= ~E1000_RCTL_VFE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		if (netdev->flags & IFF_ALLMULTI)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			rctl |= E1000_RCTL_MPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			rctl &= ~E1000_RCTL_MPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
		/* Enable VLAN filter if there is a VLAN */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		if (adapter->vlgrp)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			rctl |= E1000_RCTL_VFE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	if (netdev_uc_count(netdev) > rar_entries - 1) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		rctl |= E1000_RCTL_UPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	} else if (!(netdev->flags & IFF_PROMISC)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
		rctl &= ~E1000_RCTL_UPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
		use_uc = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
	/* 82542 2.0 needs to be in reset to write receive address registers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	if (hw->mac_type == e1000_82542_rev2_0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		e1000_enter_82542_rst(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	/* load the first 14 addresses into the exact filters 1-14. Unicast
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	 * addresses take precedence to avoid disabling unicast filtering
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	 * when possible.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	 * RAR 0 is used for the station MAC adddress
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	 * if there are not 14 addresses, go ahead and clear the filters
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	i = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	if (use_uc)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
		netdev_for_each_uc_addr(ha, netdev) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			if (i == rar_entries)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			e1000_rar_set(hw, ha->addr, i++);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	netdev_for_each_mc_addr(ha, netdev) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
		if (i == rar_entries) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			/* load any remaining addresses into the hash table */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			u32 hash_reg, hash_bit, mta;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			hash_reg = (hash_value >> 5) & 0x7F;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			hash_bit = hash_value & 0x1F;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			mta = (1 << hash_bit);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			mcarray[hash_reg] |= mta;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			e1000_rar_set(hw, ha->addr, i++);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	for (; i < rar_entries; i++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	/* write the hash table completely, write from bottom to avoid
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	 * both stupid write combining chipsets, and flushing each write */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		 * If we are on an 82544 has an errata where writing odd
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		 * offsets overwrites the previous even offset, but writing
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
		 * backwards over the range solves the issue by always
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		 * writing the odd offset first
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	if (hw->mac_type == e1000_82542_rev2_0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		e1000_leave_82542_rst(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	kfree(mcarray);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
/* Need to wait a few seconds after link up to get diagnostic information from
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
 * the phy */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
static void e1000_update_phy_info(unsigned long data)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	e1000_phy_get_info(hw, &adapter->phy_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
 * e1000_82547_tx_fifo_stall - Timer Call-back
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
 * @data: pointer to adapter cast into an unsigned long
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
static void e1000_82547_tx_fifo_stall(unsigned long data)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	u32 tctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	if (atomic_read(&adapter->tx_fifo_stall)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		if ((er32(TDT) == er32(TDH)) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
		   (er32(TDFT) == er32(TDFH)) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
		   (er32(TDFTS) == er32(TDFHS))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
			tctl = er32(TCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
			ew32(TDFT, adapter->tx_head_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			ew32(TDFH, adapter->tx_head_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			ew32(TDFTS, adapter->tx_head_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			ew32(TDFHS, adapter->tx_head_addr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			ew32(TCTL, tctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
			adapter->tx_fifo_head = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			atomic_set(&adapter->tx_fifo_stall, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			netif_wake_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
bool e1000_has_link(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	bool link_active = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	/* get_link_status is set on LSC (link status) interrupt or
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	 * rx sequence error interrupt.  get_link_status will stay
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	 * false until the e1000_check_for_link establishes link
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	 * for copper adapters ONLY
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	switch (hw->media_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	case e1000_media_type_copper:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
		if (hw->get_link_status) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
			e1000_check_for_link(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
			link_active = !hw->get_link_status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			link_active = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	case e1000_media_type_fiber:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		e1000_check_for_link(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	case e1000_media_type_internal_serdes:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		e1000_check_for_link(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		link_active = hw->serdes_has_link;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	return link_active;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 * e1000_watchdog - Timer Call-back
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 * @data: pointer to adapter cast into an unsigned long
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
static void e1000_watchdog(unsigned long data)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	struct e1000_tx_ring *txdr = adapter->tx_ring;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	u32 link, tctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	link = e1000_has_link(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	if ((netif_carrier_ok(netdev)) && link)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
		goto link_up;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	if (link) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
		if (!netif_carrier_ok(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
			u32 ctrl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
			bool txb2b = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
			/* update snapshot of PHY registers on LSC */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
			e1000_get_speed_and_duplex(hw,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
			                           &adapter->link_speed,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			                           &adapter->link_duplex);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
			ctrl = er32(CTRL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			pr_info("%s NIC Link is Up %d Mbps %s, "
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
				"Flow Control: %s\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
				netdev->name,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
				adapter->link_speed,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
				adapter->link_duplex == FULL_DUPLEX ?
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
				"Full Duplex" : "Half Duplex",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
				E1000_CTRL_TFCE) ? "TX" : "None")));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			/* adjust timeout factor according to speed/duplex */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			adapter->tx_timeout_factor = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
			switch (adapter->link_speed) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
			case SPEED_10:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
				txb2b = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
				adapter->tx_timeout_factor = 16;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
			case SPEED_100:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
				txb2b = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
				/* maybe add some timeout factor ? */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			/* enable transmits in the hardware */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
			tctl = er32(TCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
			tctl |= E1000_TCTL_EN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
			ew32(TCTL, tctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
			netif_carrier_on(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
			if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
				mod_timer(&adapter->phy_info_timer,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
				          round_jiffies(jiffies + 2 * HZ));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
			adapter->smartspeed = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		if (netif_carrier_ok(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
			adapter->link_speed = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			adapter->link_duplex = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
			pr_info("%s NIC Link is Down\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
				netdev->name);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
			netif_carrier_off(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
			if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
				mod_timer(&adapter->phy_info_timer,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
				          round_jiffies(jiffies + 2 * HZ));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		e1000_smartspeed(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
link_up:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	e1000_update_stats(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	adapter->tpt_old = adapter->stats.tpt;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	adapter->colc_old = adapter->stats.colc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	adapter->gorcl_old = adapter->stats.gorcl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	adapter->gotcl_old = adapter->stats.gotcl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	e1000_update_adaptive(hw);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	if (!netif_carrier_ok(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			/* We've lost link, so the controller stops DMA,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			 * but we've got queued Tx work that's never going
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			 * to get done, so reset controller to flush Tx.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			 * (Do the reset outside of interrupt context). */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			adapter->tx_timeout_count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			schedule_work(&adapter->reset_task);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			/* return immediately since reset is imminent */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	/* Simple mode for Interrupt Throttle Rate (ITR) */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		 * Total asymmetrical Tx or Rx gets ITR=8000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		 * everyone else is between 2000-8000.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		u32 dif = (adapter->gotcl > adapter->gorcl ?
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			    adapter->gotcl - adapter->gorcl :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
			    adapter->gorcl - adapter->gotcl) / 10000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		ew32(ITR, 1000000000 / (itr * 256));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	/* Cause software interrupt to ensure rx ring is cleaned */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	ew32(ICS, E1000_ICS_RXDMT0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	/* Force detection of hung controller every watchdog period */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	adapter->detect_tx_hung = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	/* Reset the timer */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		mod_timer(&adapter->watchdog_timer,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
		          round_jiffies(jiffies + 2 * HZ));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
enum latency_range {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	lowest_latency = 0,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	low_latency = 1,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	bulk_latency = 2,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	latency_invalid = 255
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
};
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
 * e1000_update_itr - update the dynamic ITR value based on statistics
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
 * @adapter: pointer to adapter
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
 * @itr_setting: current adapter->itr
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
 * @packets: the number of packets during this measurement interval
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
 * @bytes: the number of bytes during this measurement interval
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
 *      Stores a new ITR value based on packets and byte
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
 *      counts during the last interrupt.  The advantage of per interrupt
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
 *      computation is faster updates and more accurate ITR for the current
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
 *      traffic pattern.  Constants in this function were computed
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
 *      based on theoretical maximum wire speed and thresholds were set based
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
 *      on testing data as well as attempting to minimize response time
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
 *      while increasing bulk throughput.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
 *      this functionality is controlled by the InterruptThrottleRate module
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 *      parameter (see e1000_param.c)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
				     u16 itr_setting, int packets, int bytes)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	unsigned int retval = itr_setting;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	if (unlikely(hw->mac_type < e1000_82540))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		goto update_itr_done;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	if (packets == 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		goto update_itr_done;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	switch (itr_setting) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	case lowest_latency:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		/* jumbo frames get bulk treatment*/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		if (bytes/packets > 8000)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
			retval = bulk_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		else if ((packets < 5) && (bytes > 512))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
			retval = low_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	case low_latency:  /* 50 usec aka 20000 ints/s */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		if (bytes > 10000) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			/* jumbo frames need bulk latency setting */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
			if (bytes/packets > 8000)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
				retval = bulk_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			else if ((packets < 10) || ((bytes/packets) > 1200))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
				retval = bulk_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			else if ((packets > 35))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
				retval = lowest_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		} else if (bytes/packets > 2000)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
			retval = bulk_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		else if (packets <= 2 && bytes < 512)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			retval = lowest_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	case bulk_latency: /* 250 usec aka 4000 ints/s */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		if (bytes > 25000) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			if (packets > 35)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
				retval = low_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		} else if (bytes < 6000) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			retval = low_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
update_itr_done:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	return retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
static void e1000_set_itr(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	u16 current_itr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	u32 new_itr = adapter->itr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (unlikely(hw->mac_type < e1000_82540))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	if (unlikely(adapter->link_speed != SPEED_1000)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		current_itr = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		new_itr = 4000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		goto set_itr_now;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	adapter->tx_itr = e1000_update_itr(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	                            adapter->tx_itr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	                            adapter->total_tx_packets,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	                            adapter->total_tx_bytes);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		adapter->tx_itr = low_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	adapter->rx_itr = e1000_update_itr(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	                            adapter->rx_itr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	                            adapter->total_rx_packets,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	                            adapter->total_rx_bytes);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		adapter->rx_itr = low_latency;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	switch (current_itr) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	/* counts and packets in update_itr are dependent on these numbers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	case lowest_latency:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		new_itr = 70000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	case low_latency:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		new_itr = 20000; /* aka hwitr = ~200 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	case bulk_latency:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		new_itr = 4000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
set_itr_now:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	if (new_itr != adapter->itr) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		/* this attempts to bias the interrupt rate towards Bulk
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		 * by adding intermediate steps when interrupt rate is
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		 * increasing */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		new_itr = new_itr > adapter->itr ?
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		             min(adapter->itr + (new_itr >> 2), new_itr) :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		             new_itr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		adapter->itr = new_itr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		ew32(ITR, 1000000000 / (new_itr * 256));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
#define E1000_TX_FLAGS_CSUM		0x00000001
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
#define E1000_TX_FLAGS_VLAN		0x00000002
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
#define E1000_TX_FLAGS_TSO		0x00000004
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
#define E1000_TX_FLAGS_IPV4		0x00000008
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
#define E1000_TX_FLAGS_VLAN_SHIFT	16
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
static int e1000_tso(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	struct e1000_context_desc *context_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	u32 cmd_length = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	u16 ipcse = 0, tucse, mss;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	int err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	if (skb_is_gso(skb)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		if (skb_header_cloned(skb)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
				return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		mss = skb_shinfo(skb)->gso_size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		if (skb->protocol == htons(ETH_P_IP)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
			struct iphdr *iph = ip_hdr(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
			iph->tot_len = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
			iph->check = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
								 iph->daddr, 0,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
								 IPPROTO_TCP,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
								 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			cmd_length = E1000_TXD_CMD_IP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
			ipcse = skb_transport_offset(skb) - 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			ipv6_hdr(skb)->payload_len = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			tcp_hdr(skb)->check =
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
						 &ipv6_hdr(skb)->daddr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
						 0, IPPROTO_TCP, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
			ipcse = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		ipcss = skb_network_offset(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		tucss = skb_transport_offset(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		tucse = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		i = tx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		context_desc->upper_setup.tcp_fields.tucss = tucss;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		context_desc->upper_setup.tcp_fields.tucso = tucso;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		buffer_info->time_stamp = jiffies;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		buffer_info->next_to_watch = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		if (++i == tx_ring->count) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
		tx_ring->next_to_use = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		return true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	return false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
static bool e1000_tx_csum(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	struct e1000_context_desc *context_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	u8 css;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	u32 cmd_len = E1000_TXD_CMD_DEXT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	if (skb->ip_summed != CHECKSUM_PARTIAL)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		return false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	switch (skb->protocol) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	case cpu_to_be16(ETH_P_IP):
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			cmd_len |= E1000_TXD_CMD_TCP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	case cpu_to_be16(ETH_P_IPV6):
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		/* XXX not handling all IPV6 headers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
			cmd_len |= E1000_TXD_CMD_TCP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		if (unlikely(net_ratelimit()))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			e_warn("checksum_partial proto=%x!\n", skb->protocol);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	css = skb_transport_offset(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	i = tx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	context_desc->lower_setup.ip_config = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	context_desc->upper_setup.tcp_fields.tucss = css;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	context_desc->upper_setup.tcp_fields.tucso =
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		css + skb->csum_offset;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	context_desc->upper_setup.tcp_fields.tucse = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	context_desc->tcp_seg_setup.data = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	buffer_info->time_stamp = jiffies;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	buffer_info->next_to_watch = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	if (unlikely(++i == tx_ring->count)) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	tx_ring->next_to_use = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	return true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
#define E1000_MAX_TXD_PWR	12
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
static int e1000_tx_map(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			struct e1000_tx_ring *tx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			struct sk_buff *skb, unsigned int first,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
			unsigned int max_per_txd, unsigned int nr_frags,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
			unsigned int mss)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	unsigned int len = skb_headlen(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	unsigned int offset = 0, size, count = 0, i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	unsigned int f;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	i = tx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	while (len) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		size = min(len, max_per_txd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		/* Workaround for Controller erratum --
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		 * descriptor for non-tso packet in a linear SKB that follows a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		 * tso gets written back prematurely before the data is fully
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		 * DMA'd to the controller */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		if (!skb->data_len && tx_ring->last_tx_tso &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		    !skb_is_gso(skb)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			tx_ring->last_tx_tso = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			size -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		/* Workaround for premature desc write-backs
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		 * in TSO mode.  Append 4-byte sentinel desc */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		if (unlikely(mss && !nr_frags && size == len && size > 8))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
			size -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		/* work-around for errata 10 and it applies
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		 * to all controllers in PCI-X mode
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		 * The fix is to make sure that the first descriptor of a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		                (size > 2015) && count == 0))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		        size = 2015;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		 * terminating buffers within evenly-aligned dwords. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		if (unlikely(adapter->pcix_82544 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		   size > 4))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			size -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		buffer_info->length = size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		/* set time_stamp *before* dma to help avoid a possible race */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
		buffer_info->time_stamp = jiffies;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		buffer_info->mapped_as_page = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		buffer_info->dma = dma_map_single(&pdev->dev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
						  skb->data + offset,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
						  size,	DMA_TO_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
			goto dma_error;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		buffer_info->next_to_watch = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		len -= size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		offset += size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
		count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		if (len) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			i++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
			if (unlikely(i == tx_ring->count))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
				i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	for (f = 0; f < nr_frags; f++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		struct skb_frag_struct *frag;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		frag = &skb_shinfo(skb)->frags[f];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		len = frag->size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		offset = frag->page_offset;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		while (len) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			i++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
			if (unlikely(i == tx_ring->count))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
				i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
			buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			size = min(len, max_per_txd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			/* Workaround for premature desc write-backs
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
			 * in TSO mode.  Append 4-byte sentinel desc */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
				size -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
			/* Workaround for potential 82544 hang in PCI-X.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
			 * Avoid terminating buffers within evenly-aligned
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			 * dwords. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			if (unlikely(adapter->pcix_82544 &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			    !((unsigned long)(page_to_phys(frag->page) + offset
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			                      + size - 1) & 4) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			    size > 4))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
				size -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
			buffer_info->length = size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
			buffer_info->time_stamp = jiffies;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
			buffer_info->mapped_as_page = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
							offset,	size,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
							DMA_TO_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
				goto dma_error;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
			buffer_info->next_to_watch = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
			len -= size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
			offset += size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
			count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	tx_ring->buffer_info[i].skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	tx_ring->buffer_info[first].next_to_watch = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	return count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
dma_error:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	dev_err(&pdev->dev, "TX DMA map failed\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	if (count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		count--;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	while (count--) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		if (i==0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			i += tx_ring->count;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		i--;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
static void e1000_tx_queue(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
			   struct e1000_tx_ring *tx_ring, int tx_flags,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
			   int count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	struct e1000_tx_desc *tx_desc = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		             E1000_TXD_CMD_TSE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		txd_lower |= E1000_TXD_CMD_VLE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	i = tx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	while (count--) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		tx_desc = E1000_TX_DESC(*tx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		tx_desc->lower.data =
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
			cpu_to_le32(txd_lower | buffer_info->length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		tx_desc->upper.data = cpu_to_le32(txd_upper);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		if (unlikely(++i == tx_ring->count)) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	/* Force memory writes to complete before letting h/w
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	 * know there are new descriptors to fetch.  (Only
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	 * applicable for weak-ordered memory model archs,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	 * such as IA-64). */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	wmb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	tx_ring->next_to_use = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	writel(i, hw->hw_addr + tx_ring->tdt);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	/* we need this if more than one processor can write to our tail
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	 * at a time, it syncronizes IO on IA64/Altix systems */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	mmiowb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 * 82547 workaround to avoid controller hang in half-duplex environment.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 * The workaround is to avoid queuing a large packet that would span
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
 * the internal Tx FIFO ring boundary by notifying the stack to resend
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
 * to the beginning of the Tx FIFO.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
#define E1000_FIFO_HDR			0x10
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
#define E1000_82547_PAD_LEN		0x3E0
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
				       struct sk_buff *skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	if (adapter->link_duplex != HALF_DUPLEX)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		goto no_fifo_stall_required;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	if (atomic_read(&adapter->tx_fifo_stall))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		return 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		atomic_set(&adapter->tx_fifo_stall, 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
		return 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
no_fifo_stall_required:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	adapter->tx_fifo_head += skb_fifo_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	netif_stop_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	/* Herbert's original patch had:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	 *  smp_mb__after_netif_stop_queue();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	 * but since that doesn't exist yet, just open code it. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	smp_mb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	/* We need to check again in a case another CPU has just
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	 * made room available. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		return -EBUSY;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	/* A reprieve! */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	netif_start_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	++adapter->restart_queue;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
static int e1000_maybe_stop_tx(struct net_device *netdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
                               struct e1000_tx_ring *tx_ring, int size)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	return __e1000_maybe_stop_tx(netdev, size);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
				    struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	struct e1000_tx_ring *tx_ring;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	unsigned int tx_flags = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	unsigned int len = skb_headlen(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	unsigned int nr_frags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	unsigned int mss;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	int count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	int tso;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	unsigned int f;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	/* This goes back to the question of how to logically map a tx queue
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	 * to a flow.  Right now, performance is impacted slightly negatively
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	 * if using multiple tx queues.  If the stack breaks away from a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	 * single qdisc implementation, we can look at this again. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	tx_ring = adapter->tx_ring;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	if (unlikely(skb->len <= 0)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		dev_kfree_skb_any(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		return NETDEV_TX_OK;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	mss = skb_shinfo(skb)->gso_size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	/* The controller does a simple calculation to
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	 * make sure there is enough room in the FIFO before
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	 * initiating the DMA for each buffer.  The calc is:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	 * 4 = ceil(buffer len/mss).  To make sure we don't
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	 * overrun the FIFO, adjust the max buffer len if mss
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	 * drops. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	if (mss) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		u8 hdr_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		max_per_txd = min(mss << 2, max_per_txd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
		max_txd_pwr = fls(max_per_txd) - 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		if (skb->data_len && hdr_len == len) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
			switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
				unsigned int pull_size;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			case e1000_82544:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
				/* Make sure we have room to chop off 4 bytes,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
				 * and that the end alignment will work out to
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
				 * this hardware's requirements
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
				 * NOTE: this is a TSO only workaround
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
				 * if end byte alignment not correct move us
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
				 * into the next dword */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
					break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
				/* fall through */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
				pull_size = min((unsigned int)4, skb->data_len);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
				if (!__pskb_pull_tail(skb, pull_size)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
					e_err("__pskb_pull_tail failed.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
					dev_kfree_skb_any(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
					return NETDEV_TX_OK;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
				}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
				len = skb_headlen(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
			default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
				/* do nothing */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	/* reserve a descriptor for the offload context */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	/* Controller Erratum workaround */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	count += TXD_USE_COUNT(len, max_txd_pwr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	if (adapter->pcix_82544)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	/* work-around for errata 10 and it applies to all controllers
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	 * in PCI-X mode, so add one more descriptor to the count
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			(len > 2015)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	nr_frags = skb_shinfo(skb)->nr_frags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	for (f = 0; f < nr_frags; f++)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
				       max_txd_pwr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	if (adapter->pcix_82544)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		count += nr_frags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	/* need: count + 2 desc gap to keep tail from touching
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	 * head, otherwise try next time */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		return NETDEV_TX_BUSY;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	if (unlikely(hw->mac_type == e1000_82547)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
			netif_stop_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
				mod_timer(&adapter->tx_fifo_stall_timer,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
				          jiffies + 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			return NETDEV_TX_BUSY;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		tx_flags |= E1000_TX_FLAGS_VLAN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	first = tx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	tso = e1000_tso(adapter, tx_ring, skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	if (tso < 0) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		dev_kfree_skb_any(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		return NETDEV_TX_OK;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	if (likely(tso)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		if (likely(hw->mac_type != e1000_82544))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
			tx_ring->last_tx_tso = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		tx_flags |= E1000_TX_FLAGS_TSO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		tx_flags |= E1000_TX_FLAGS_CSUM;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	if (likely(skb->protocol == htons(ETH_P_IP)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		tx_flags |= E1000_TX_FLAGS_IPV4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	                     nr_frags, mss);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	if (count) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		/* Make sure there is space in the ring for the next send. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		dev_kfree_skb_any(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		tx_ring->buffer_info[first].time_stamp = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		tx_ring->next_to_use = first;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	return NETDEV_TX_OK;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
 * e1000_tx_timeout - Respond to a Tx Hang
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
static void e1000_tx_timeout(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	/* Do the reset outside of interrupt context */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	adapter->tx_timeout_count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	schedule_work(&adapter->reset_task);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
static void e1000_reset_task(struct work_struct *work)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	struct e1000_adapter *adapter =
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		container_of(work, struct e1000_adapter, reset_task);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	e1000_reinit_locked(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 * e1000_get_stats - Get System Network Statistics
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
 * Returns the address of the device statistics structure.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 * The statistics are actually updated from the timer callback.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	/* only return the current stats */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	return &netdev->stats;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 * e1000_change_mtu - Change the Maximum Transfer Unit
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
 * @netdev: network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
 * @new_mtu: new value for maximum frame size
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
 * Returns 0 on success, negative on failure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		e_err("Invalid MTU setting\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		return -EINVAL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	/* Adapter-specific max frame size limits. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	switch (hw->mac_type) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	case e1000_undefined ... e1000_82542_rev2_1:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
			e_err("Jumbo Frames not supported.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
			return -EINVAL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		msleep(1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	/* e1000_down has a dependency on max_frame_size */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	hw->max_frame_size = max_frame;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		e1000_down(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	 * means we reserve 2 more, this pushes us to allocate from the next
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	 * larger slab size.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	 * i.e. RXBUFFER_2048 --> size-4096 slab
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	 *  fragmented skbs */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	if (max_frame <= E1000_RXBUFFER_2048)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
		adapter->rx_buffer_len = PAGE_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	/* adjust allocation if LPE protects us, and we aren't using SBP */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	if (!hw->tbi_compatibility_on &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	pr_info("%s changing MTU from %d to %d\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		netdev->name, netdev->mtu, new_mtu);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	netdev->mtu = new_mtu;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		e1000_up(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
		e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	clear_bit(__E1000_RESETTING, &adapter->flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
 * e1000_update_stats - Update the board statistics counters
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
void e1000_update_stats(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	unsigned long flags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	u16 phy_tmp;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	 * Prevent stats update while adapter is being reset, or if the pci
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	 * connection is down.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	if (adapter->link_speed == 0)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	if (pci_channel_offline(pdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	spin_lock_irqsave(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	/* these counters are modified from e1000_tbi_adjust_stats,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	 * called from the interrupt context, so they must only
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	 * be written while holding adapter->stats_lock
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	adapter->stats.crcerrs += er32(CRCERRS);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	adapter->stats.gprc += er32(GPRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	adapter->stats.gorcl += er32(GORCL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	adapter->stats.gorch += er32(GORCH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	adapter->stats.bprc += er32(BPRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	adapter->stats.mprc += er32(MPRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	adapter->stats.roc += er32(ROC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	adapter->stats.prc64 += er32(PRC64);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	adapter->stats.prc127 += er32(PRC127);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	adapter->stats.prc255 += er32(PRC255);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	adapter->stats.prc511 += er32(PRC511);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	adapter->stats.prc1023 += er32(PRC1023);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	adapter->stats.prc1522 += er32(PRC1522);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	adapter->stats.symerrs += er32(SYMERRS);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	adapter->stats.mpc += er32(MPC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	adapter->stats.scc += er32(SCC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	adapter->stats.ecol += er32(ECOL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	adapter->stats.mcc += er32(MCC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	adapter->stats.latecol += er32(LATECOL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	adapter->stats.dc += er32(DC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	adapter->stats.sec += er32(SEC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	adapter->stats.rlec += er32(RLEC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	adapter->stats.xonrxc += er32(XONRXC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	adapter->stats.xontxc += er32(XONTXC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	adapter->stats.xoffrxc += er32(XOFFRXC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	adapter->stats.xofftxc += er32(XOFFTXC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	adapter->stats.fcruc += er32(FCRUC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	adapter->stats.gptc += er32(GPTC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	adapter->stats.gotcl += er32(GOTCL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
	adapter->stats.gotch += er32(GOTCH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	adapter->stats.rnbc += er32(RNBC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	adapter->stats.ruc += er32(RUC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	adapter->stats.rfc += er32(RFC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	adapter->stats.rjc += er32(RJC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	adapter->stats.torl += er32(TORL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	adapter->stats.torh += er32(TORH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	adapter->stats.totl += er32(TOTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	adapter->stats.toth += er32(TOTH);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	adapter->stats.tpr += er32(TPR);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	adapter->stats.ptc64 += er32(PTC64);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	adapter->stats.ptc127 += er32(PTC127);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	adapter->stats.ptc255 += er32(PTC255);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	adapter->stats.ptc511 += er32(PTC511);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	adapter->stats.ptc1023 += er32(PTC1023);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	adapter->stats.ptc1522 += er32(PTC1522);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	adapter->stats.mptc += er32(MPTC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	adapter->stats.bptc += er32(BPTC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	/* used for adaptive IFS */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	hw->tx_packet_delta = er32(TPT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	adapter->stats.tpt += hw->tx_packet_delta;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	hw->collision_delta = er32(COLC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	adapter->stats.colc += hw->collision_delta;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	if (hw->mac_type >= e1000_82543) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		adapter->stats.algnerrc += er32(ALGNERRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
		adapter->stats.rxerrc += er32(RXERRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
		adapter->stats.tncrs += er32(TNCRS);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
		adapter->stats.cexterr += er32(CEXTERR);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		adapter->stats.tsctc += er32(TSCTC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		adapter->stats.tsctfc += er32(TSCTFC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	/* Fill out the OS statistics structure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	netdev->stats.multicast = adapter->stats.mprc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	netdev->stats.collisions = adapter->stats.colc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	/* Rx Errors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	/* RLEC on some newer hardware can be incorrect so build
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	* our own version based on RUC and ROC */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	netdev->stats.rx_errors = adapter->stats.rxerrc +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		adapter->stats.crcerrs + adapter->stats.algnerrc +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		adapter->stats.ruc + adapter->stats.roc +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		adapter->stats.cexterr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	/* Tx Errors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	netdev->stats.tx_errors = adapter->stats.txerrc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	netdev->stats.tx_window_errors = adapter->stats.latecol;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	if (hw->bad_tx_carr_stats_fd &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	    adapter->link_duplex == FULL_DUPLEX) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		netdev->stats.tx_carrier_errors = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		adapter->stats.tncrs = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	/* Tx Dropped needs to be maintained elsewhere */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	/* Phy Stats */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	if (hw->media_type == e1000_media_type_copper) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		if ((adapter->link_speed == SPEED_1000) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
			adapter->phy_stats.idle_errors += phy_tmp;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		if ((hw->mac_type <= e1000_82546) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		   (hw->phy_type == e1000_phy_m88) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
			adapter->phy_stats.receive_errors += phy_tmp;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	/* Management Stats */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	if (hw->has_smbus) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
		adapter->stats.mgptc += er32(MGTPTC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		adapter->stats.mgprc += er32(MGTPRC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		adapter->stats.mgpdc += er32(MGTPDC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
 * e1000_intr - Interrupt Handler
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
 * @irq: interrupt number
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
 * @data: pointer to a network interface device structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
static irqreturn_t e1000_intr(int irq, void *data)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	struct net_device *netdev = data;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	u32 icr = er32(ICR);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		return IRQ_NONE;  /* Not our interrupt */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		hw->get_link_status = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		/* guard against interrupt when we're going down */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
		if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	/* disable interrupts, without the synchronize_irq bit */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	ew32(IMC, ~0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	E1000_WRITE_FLUSH();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	if (likely(napi_schedule_prep(&adapter->napi))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		adapter->total_tx_bytes = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		adapter->total_tx_packets = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		adapter->total_rx_bytes = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		adapter->total_rx_packets = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		__napi_schedule(&adapter->napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		/* this really should not happen! if it does it is basically a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		 * bug, but not a hard error, so enable ints and continue */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
			e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	return IRQ_HANDLED;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
 * e1000_clean - NAPI Rx polling callback
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
static int e1000_clean(struct napi_struct *napi, int budget)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	int tx_clean_complete = 0, work_done = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	if (!tx_clean_complete)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		work_done = budget;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	/* If budget not fully consumed, exit the polling mode */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	if (work_done < budget) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		if (likely(adapter->itr_setting & 3))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
			e1000_set_itr(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		napi_complete(napi);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
		if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
			e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	return work_done;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
			       struct e1000_tx_ring *tx_ring)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	struct e1000_tx_desc *tx_desc, *eop_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	unsigned int i, eop;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	unsigned int count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	unsigned int total_tx_bytes=0, total_tx_packets=0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	i = tx_ring->next_to_clean;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	eop = tx_ring->buffer_info[i].next_to_watch;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	       (count < tx_ring->count)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		bool cleaned = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		rmb();	/* read buffer_info after eop_desc */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		for ( ; !cleaned; count++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
			tx_desc = E1000_TX_DESC(*tx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
			buffer_info = &tx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			cleaned = (i == eop);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
			if (cleaned) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
				struct sk_buff *skb = buffer_info->skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
				unsigned int segs, bytecount;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
				segs = skb_shinfo(skb)->gso_segs ?: 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
				/* multiply data chunks by size of headers */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
				bytecount = ((segs - 1) * skb_headlen(skb)) +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
				            skb->len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
				total_tx_packets += segs;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
				total_tx_bytes += bytecount;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
			tx_desc->upper.data = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
			if (unlikely(++i == tx_ring->count)) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
		eop = tx_ring->buffer_info[i].next_to_watch;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	tx_ring->next_to_clean = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
#define TX_WAKE_THRESHOLD 32
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	if (unlikely(count && netif_carrier_ok(netdev) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		/* Make sure that anybody stopping the queue after this
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
		 * sees the new next_to_clean.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
		smp_mb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
		if (netif_queue_stopped(netdev) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
			netif_wake_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
			++adapter->restart_queue;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	if (adapter->detect_tx_hung) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
		/* Detect a transmit hang in hardware, this serializes the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		 * check with the clearing of time_stamp and movement of i */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		adapter->detect_tx_hung = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		if (tx_ring->buffer_info[eop].time_stamp &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
		               (adapter->tx_timeout_factor * HZ)) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
			/* detected Tx unit hang */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			e_err("Detected Tx Unit Hang\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
			      "  Tx Queue             <%lu>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			      "  TDH                  <%x>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
			      "  TDT                  <%x>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
			      "  next_to_use          <%x>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
			      "  next_to_clean        <%x>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
			      "buffer_info[next_to_clean]\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
			      "  time_stamp           <%lx>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
			      "  next_to_watch        <%x>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
			      "  jiffies              <%lx>\n"
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
			      "  next_to_watch.status <%x>\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
				(unsigned long)((tx_ring - adapter->tx_ring) /
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
					sizeof(struct e1000_tx_ring)),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
				readl(hw->hw_addr + tx_ring->tdh),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
				readl(hw->hw_addr + tx_ring->tdt),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
				tx_ring->next_to_use,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
				tx_ring->next_to_clean,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
				tx_ring->buffer_info[eop].time_stamp,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
				eop,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
				jiffies,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
				eop_desc->upper.fields.status);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
			netif_stop_queue(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	adapter->total_tx_bytes += total_tx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	adapter->total_tx_packets += total_tx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	netdev->stats.tx_bytes += total_tx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	netdev->stats.tx_packets += total_tx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	return (count < tx_ring->count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
 * e1000_rx_checksum - Receive Checksum Offload for 82543
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
 * @adapter:     board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
 * @status_err:  receive descriptor status and error fields
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
 * @csum:        receive descriptor csum field
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
 * @sk_buff:     socket buffer with received data
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
			      u32 csum, struct sk_buff *skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	u16 status = (u16)status_err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
	u8 errors = (u8)(status_err >> 24);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	skb->ip_summed = CHECKSUM_NONE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	/* 82543 or newer only */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	if (unlikely(hw->mac_type < e1000_82543)) return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
	/* Ignore Checksum bit is set */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	/* TCP/UDP checksum error bit is set */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		/* let the stack verify checksum errors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		adapter->hw_csum_err++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	/* TCP/UDP Checksum has not been calculated */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	if (!(status & E1000_RXD_STAT_TCPCS))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* It must be a TCP or UDP packet with a valid checksum */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		/* TCP checksum is good */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		skb->ip_summed = CHECKSUM_UNNECESSARY;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	adapter->hw_csum_good++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
 * e1000_consume_page - helper function
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
                               u16 length)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	bi->page = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	skb->len += length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	skb->data_len += length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	skb->truesize += length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
 * e1000_receive_skb - helper function to handle rx indications
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
 * @status: descriptor status field as written by hardware
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
 * @skb: pointer to sk_buff to be indicated to stack
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
			      __le16 vlan, struct sk_buff *skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		                         le16_to_cpu(vlan) &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		                         E1000_RXD_SPC_VLAN_MASK);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		netif_receive_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
 * @rx_ring: ring to clean
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
 * @work_done: amount of napi work completed this call
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
 * @work_to_do: max amount of work allowed for this call to do
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
 * the return value indicates whether actual cleaning was done, there
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
 * is no guarantee that everything was cleaned
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
				     struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
				     int *work_done, int work_to_do)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
	struct e1000_rx_desc *rx_desc, *next_rxd;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	struct e1000_buffer *buffer_info, *next_buffer;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	unsigned long irq_flags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	u32 length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	int cleaned_count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	bool cleaned = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	unsigned int total_rx_bytes=0, total_rx_packets=0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	i = rx_ring->next_to_clean;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	rx_desc = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	while (rx_desc->status & E1000_RXD_STAT_DD) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
		struct sk_buff *skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		u8 status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		if (*work_done >= work_to_do)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		(*work_done)++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
		rmb(); /* read descriptor and rx_buffer_info after status DD */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
		status = rx_desc->status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		skb = buffer_info->skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		if (++i == rx_ring->count) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		next_rxd = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		prefetch(next_rxd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		next_buffer = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
		cleaned = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		cleaned_count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		dma_unmap_page(&pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
			       buffer_info->length, DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		length = le16_to_cpu(rx_desc->length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		/* errors is only valid for DD + EOP descriptors */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
			u8 last_byte = *(skb->data + length - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
				       last_byte)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
				spin_lock_irqsave(&adapter->stats_lock,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
				                  irq_flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
				e1000_tbi_adjust_stats(hw, &adapter->stats,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
				                       length, skb->data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
				spin_unlock_irqrestore(&adapter->stats_lock,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
				                       irq_flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
				length--;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
			} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
				/* recycle both page and skb */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
				buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
				/* an error means any chain goes out the window
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
				 * too */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
				if (rx_ring->rx_skb_top)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
					dev_kfree_skb(rx_ring->rx_skb_top);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
				rx_ring->rx_skb_top = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
				goto next_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
#define rxtop rx_ring->rx_skb_top
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
		if (!(status & E1000_RXD_STAT_EOP)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
			/* this descriptor is only the beginning (or middle) */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
			if (!rxtop) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
				/* this is the beginning of a chain */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
				rxtop = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
				                   0, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
			} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
				/* this is the middle of a chain */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
				skb_fill_page_desc(rxtop,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
				    skb_shinfo(rxtop)->nr_frags,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
				    buffer_info->page, 0, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
				/* re-use the skb, only consumed the page */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
				buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
			e1000_consume_page(buffer_info, rxtop, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			goto next_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
			if (rxtop) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
				/* end of the chain */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
				skb_fill_page_desc(rxtop,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
				    skb_shinfo(rxtop)->nr_frags,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
				    buffer_info->page, 0, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
				/* re-use the current skb, we only consumed the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
				 * page */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
				buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
				skb = rxtop;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
				rxtop = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
				e1000_consume_page(buffer_info, skb, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
				/* no chain, got EOP, this buf is the packet
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
				 * copybreak to save the put_page/alloc_page */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
				if (length <= copybreak &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
				    skb_tailroom(skb) >= length) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
					u8 *vaddr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
					vaddr = kmap_atomic(buffer_info->page,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
					                    KM_SKB_DATA_SOFTIRQ);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
					memcpy(skb_tail_pointer(skb), vaddr, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
					kunmap_atomic(vaddr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
					              KM_SKB_DATA_SOFTIRQ);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
					/* re-use the page, so don't erase
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
					 * buffer_info->page */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
					skb_put(skb, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
				} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
					skb_fill_page_desc(skb, 0,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
					                   buffer_info->page, 0,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
				                           length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
					e1000_consume_page(buffer_info, skb,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
					                   length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
				}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		e1000_rx_checksum(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		                  (u32)(status) |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		                  ((u32)(rx_desc->errors) << 24),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		                  le16_to_cpu(rx_desc->csum), skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		pskb_trim(skb, skb->len - 4);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		/* probably a little skewed due to removing CRC */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		total_rx_bytes += skb->len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		total_rx_packets++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		/* eth type trans needs skb->data to point to something */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		if (!pskb_may_pull(skb, ETH_HLEN)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
			e_err("pskb_may_pull failed.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
			dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
			goto next_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		skb->protocol = eth_type_trans(skb, netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
next_desc:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		rx_desc->status = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		/* return some buffers to hardware, one at a time is too slow */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
			cleaned_count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		/* use prefetched values */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		rx_desc = next_rxd;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
		buffer_info = next_buffer;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	rx_ring->next_to_clean = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	if (cleaned_count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	adapter->total_rx_packets += total_rx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	adapter->total_rx_bytes += total_rx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	netdev->stats.rx_bytes += total_rx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	netdev->stats.rx_packets += total_rx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	return cleaned;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
 * this should improve performance for small packets with large amounts
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
 * of reassembly being done in the stack
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
static void e1000_check_copybreak(struct net_device *netdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
				 struct e1000_buffer *buffer_info,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
				 u32 length, struct sk_buff **skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	struct sk_buff *new_skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	if (length > copybreak)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	if (!new_skb)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
				       (*skb)->data - NET_IP_ALIGN,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
				       length + NET_IP_ALIGN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	/* save the skb in buffer_info as good */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	buffer_info->skb = *skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	*skb = new_skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
 * @adapter: board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
 * @rx_ring: ring to clean
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
 * @work_done: amount of napi work completed this call
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
 * @work_to_do: max amount of work allowed for this call to do
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
			       struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
			       int *work_done, int work_to_do)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	struct e1000_rx_desc *rx_desc, *next_rxd;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	struct e1000_buffer *buffer_info, *next_buffer;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	unsigned long flags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	u32 length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	int cleaned_count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	bool cleaned = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	unsigned int total_rx_bytes=0, total_rx_packets=0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	i = rx_ring->next_to_clean;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	rx_desc = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	while (rx_desc->status & E1000_RXD_STAT_DD) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		struct sk_buff *skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		u8 status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		if (*work_done >= work_to_do)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		(*work_done)++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		rmb(); /* read descriptor and rx_buffer_info after status DD */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		status = rx_desc->status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		skb = buffer_info->skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		prefetch(skb->data - NET_IP_ALIGN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		if (++i == rx_ring->count) i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		next_rxd = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		prefetch(next_rxd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		next_buffer = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
		cleaned = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
		cleaned_count++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		dma_unmap_single(&pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
				 buffer_info->length, DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
		length = le16_to_cpu(rx_desc->length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		/* !EOP means multiple descriptors were used to store a single
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		 * packet, if thats the case we need to toss it.  In fact, we
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
		 * to toss every packet with the EOP bit clear and the next
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		 * frame that _does_ have the EOP bit set, as it is by
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		 * definition only a frame fragment
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
			adapter->discarding = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		if (adapter->discarding) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
			/* All receives must fit into a single buffer */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
			e_info("Receive packet consumed multiple buffers\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
			/* recycle */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
			buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
			if (status & E1000_RXD_STAT_EOP)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
				adapter->discarding = false;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
			goto next_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
			u8 last_byte = *(skb->data + length - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
				       last_byte)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
				spin_lock_irqsave(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
				e1000_tbi_adjust_stats(hw, &adapter->stats,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
				                       length, skb->data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
				spin_unlock_irqrestore(&adapter->stats_lock,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
				                       flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
				length--;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
				/* recycle */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
				buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
				goto next_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		/* adjust length to remove Ethernet CRC, this must be
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		 * done after the TBI_ACCEPT workaround above */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		length -= 4;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		/* probably a little skewed due to removing CRC */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		total_rx_bytes += length;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		total_rx_packets++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		skb_put(skb, length);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		/* Receive Checksum Offload */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		e1000_rx_checksum(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
				  (u32)(status) |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
				  ((u32)(rx_desc->errors) << 24),
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
				  le16_to_cpu(rx_desc->csum), skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		skb->protocol = eth_type_trans(skb, netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
next_desc:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		rx_desc->status = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		/* return some buffers to hardware, one at a time is too slow */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
			cleaned_count = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		/* use prefetched values */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		rx_desc = next_rxd;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
		buffer_info = next_buffer;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	rx_ring->next_to_clean = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	if (cleaned_count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	adapter->total_rx_packets += total_rx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	adapter->total_rx_bytes += total_rx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	netdev->stats.rx_bytes += total_rx_bytes;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	netdev->stats.rx_packets += total_rx_packets;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	return cleaned;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
 * @adapter: address of board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
 * @rx_ring: pointer to receive ring structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
 * @cleaned_count: number of buffers to allocate this pass
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
static void
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	struct e1000_rx_desc *rx_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	struct sk_buff *skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	i = rx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	while (cleaned_count--) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		skb = buffer_info->skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		if (skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
			skb_trim(skb, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
			goto check_page;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		if (unlikely(!skb)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			/* Better luck next round */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
		/* Fix for errata 23, can't cross 64kB boundary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
			struct sk_buff *oldskb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			e_err("skb align check failed: %u bytes at %p\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
			      bufsz, skb->data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			/* Try again, without freeing the previous */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			/* Failed allocation, critical failure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
			if (!skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
				dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
				adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
				/* give up */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
				dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
				dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
				break; /* while (cleaned_count--) */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			/* Use new allocation */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
			dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		buffer_info->length = adapter->rx_buffer_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
check_page:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		/* allocate a new page if necessary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		if (!buffer_info->page) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
			buffer_info->page = alloc_page(GFP_ATOMIC);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
			if (unlikely(!buffer_info->page)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
				adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		if (!buffer_info->dma) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
			buffer_info->dma = dma_map_page(&pdev->dev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
			                                buffer_info->page, 0,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
							buffer_info->length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
							DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
				put_page(buffer_info->page);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
				dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
				buffer_info->page = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
				buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
				buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
				adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
				break; /* while !buffer_info->skb */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		rx_desc = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		if (unlikely(++i == rx_ring->count))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
			i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	if (likely(rx_ring->next_to_use != i)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
		rx_ring->next_to_use = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		if (unlikely(i-- == 0))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
			i = (rx_ring->count - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
		/* Force memory writes to complete before letting h/w
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		 * know there are new descriptors to fetch.  (Only
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		 * applicable for weak-ordered memory model archs,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		 * such as IA-64). */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		wmb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
 * @adapter: address of board private structure
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
				   struct e1000_rx_ring *rx_ring,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
				   int cleaned_count)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	struct net_device *netdev = adapter->netdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	struct pci_dev *pdev = adapter->pdev;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	struct e1000_rx_desc *rx_desc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	struct e1000_buffer *buffer_info;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	struct sk_buff *skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	unsigned int i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	unsigned int bufsz = adapter->rx_buffer_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	i = rx_ring->next_to_use;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
	buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	while (cleaned_count--) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
		skb = buffer_info->skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
		if (skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
			skb_trim(skb, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
			goto map_skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		if (unlikely(!skb)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
			/* Better luck next round */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
			adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
			break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		/* Fix for errata 23, can't cross 64kB boundary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			struct sk_buff *oldskb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			e_err("skb align check failed: %u bytes at %p\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
			      bufsz, skb->data);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
			/* Try again, without freeing the previous */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
			/* Failed allocation, critical failure */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
			if (!skb) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
				adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
				/* give up */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
				dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
				dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
				adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
				break; /* while !buffer_info->skb */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
			/* Use new allocation */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
			dev_kfree_skb(oldskb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
		buffer_info->skb = skb;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		buffer_info->length = adapter->rx_buffer_len;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
map_skb:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		buffer_info->dma = dma_map_single(&pdev->dev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
						  skb->data,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
						  buffer_info->length,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
						  DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
			dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
			buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
			adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
			break; /* while !buffer_info->skb */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		 * XXX if it was allocated cleanly it will never map to a
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		 * boundary crossing
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
		/* Fix for errata 23, can't cross 64kB boundary */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		if (!e1000_check_64k_bound(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
					(void *)(unsigned long)buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
					adapter->rx_buffer_len)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
			e_err("dma align check failed: %u bytes at %p\n",
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
			      adapter->rx_buffer_len,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			      (void *)(unsigned long)buffer_info->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
			dev_kfree_skb(skb);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
			buffer_info->skb = NULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
			dma_unmap_single(&pdev->dev, buffer_info->dma,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
					 adapter->rx_buffer_len,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
					 DMA_FROM_DEVICE);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			buffer_info->dma = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
			adapter->alloc_rx_buff_failed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			break; /* while !buffer_info->skb */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		rx_desc = E1000_RX_DESC(*rx_ring, i);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		if (unlikely(++i == rx_ring->count))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			i = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		buffer_info = &rx_ring->buffer_info[i];
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	if (likely(rx_ring->next_to_use != i)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		rx_ring->next_to_use = i;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		if (unlikely(i-- == 0))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			i = (rx_ring->count - 1);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		/* Force memory writes to complete before letting h/w
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		 * know there are new descriptors to fetch.  (Only
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		 * applicable for weak-ordered memory model archs,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		 * such as IA-64). */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		wmb();
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		writel(i, hw->hw_addr + rx_ring->rdt);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
 * @adapter:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
static void e1000_smartspeed(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	u16 phy_status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	u16 phy_ctrl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
	if (adapter->smartspeed == 0) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		/* If Master/Slave config fault is asserted twice,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		 * we assume back-to-back */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
					    phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
			adapter->smartspeed++;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
			if (!e1000_phy_setup_autoneg(hw) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
			   !e1000_read_phy_reg(hw, PHY_CTRL,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
				   	       &phy_ctrl)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
					     MII_CR_RESTART_AUTO_NEG);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
				e1000_write_phy_reg(hw, PHY_CTRL,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
						    phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
		/* If still no link, perhaps using 2/3 pair cable */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		phy_ctrl |= CR_1000T_MS_ENABLE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
		if (!e1000_phy_setup_autoneg(hw) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
				     MII_CR_RESTART_AUTO_NEG);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
		adapter->smartspeed = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
 * e1000_ioctl -
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
 * @netdev:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * @ifreq:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * @cmd:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	switch (cmd) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	case SIOCGMIIPHY:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	case SIOCGMIIREG:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
	case SIOCSMIIREG:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		return e1000_mii_ioctl(netdev, ifr, cmd);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		return -EOPNOTSUPP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
 * e1000_mii_ioctl -
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
 * @netdev:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
 * @ifreq:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
 * @cmd:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
 **/
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
			   int cmd)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	struct mii_ioctl_data *data = if_mii(ifr);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	int retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	u16 mii_reg;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	u16 spddplx;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	unsigned long flags;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	if (hw->media_type != e1000_media_type_copper)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		return -EOPNOTSUPP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	switch (cmd) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	case SIOCGMIIPHY:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		data->phy_id = hw->phy_addr;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
	case SIOCGMIIREG:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		spin_lock_irqsave(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
				   &data->val_out)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
			return -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	case SIOCSMIIREG:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		if (data->reg_num & ~(0x1F))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
			return -EFAULT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		mii_reg = data->val_in;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		spin_lock_irqsave(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		if (e1000_write_phy_reg(hw, data->reg_num,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
					mii_reg)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			return -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		if (hw->media_type == e1000_media_type_copper) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
			switch (data->reg_num) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
			case PHY_CTRL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
				if (mii_reg & MII_CR_POWER_DOWN)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
					break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
					hw->autoneg = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
					hw->autoneg_advertised = 0x2F;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
				} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
					if (mii_reg & 0x40)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
						spddplx = SPEED_1000;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
					else if (mii_reg & 0x2000)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
						spddplx = SPEED_100;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
					else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
						spddplx = SPEED_10;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
					spddplx += (mii_reg & 0x100)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
						   ? DUPLEX_FULL :
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
						   DUPLEX_HALF;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
					retval = e1000_set_spd_dplx(adapter,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
								    spddplx);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
					if (retval)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
						return retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
				}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
				if (netif_running(adapter->netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
					e1000_reinit_locked(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
				else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
					e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
			case M88E1000_PHY_SPEC_CTRL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			case M88E1000_EXT_PHY_SPEC_CTRL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
				if (e1000_phy_reset(hw))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
					return -EIO;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
			switch (data->reg_num) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			case PHY_CTRL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
				if (mii_reg & MII_CR_POWER_DOWN)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
					break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
				if (netif_running(adapter->netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
					e1000_reinit_locked(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
				else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
					e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
				break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		return -EOPNOTSUPP;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	return E1000_SUCCESS;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
void e1000_pci_set_mwi(struct e1000_hw *hw)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	struct e1000_adapter *adapter = hw->back;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	int ret_val = pci_set_mwi(adapter->pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	if (ret_val)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		e_err("Error in setting MWI\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
void e1000_pci_clear_mwi(struct e1000_hw *hw)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	struct e1000_adapter *adapter = hw->back;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	pci_clear_mwi(adapter->pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	struct e1000_adapter *adapter = hw->back;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
	return pcix_get_mmrbc(adapter->pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	struct e1000_adapter *adapter = hw->back;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	pcix_set_mmrbc(adapter->pdev, mmrbc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	outl(value, port);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
static void e1000_vlan_rx_register(struct net_device *netdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
				   struct vlan_group *grp)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	u32 ctrl, rctl;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
		e1000_irq_disable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	adapter->vlgrp = grp;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	if (grp) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		/* enable VLAN tag insert/strip */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
		ctrl = er32(CTRL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		ctrl |= E1000_CTRL_VME;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		ew32(CTRL, ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		/* enable VLAN receive filtering */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		rctl &= ~E1000_RCTL_CFIEN;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		if (!(netdev->flags & IFF_PROMISC))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
			rctl |= E1000_RCTL_VFE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
		ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		e1000_update_mng_vlan(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		/* disable VLAN tag insert/strip */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		ctrl = er32(CTRL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
		ctrl &= ~E1000_CTRL_VME;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
		ew32(CTRL, ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
		/* disable VLAN receive filtering */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		rctl &= ~E1000_RCTL_VFE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	u32 vfta, index;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	if ((hw->mng_cookie.status &
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	    (vid == adapter->mng_vlan_id))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	/* add VID to filter table */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
	index = (vid >> 5) & 0x7F;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	vfta |= (1 << (vid & 0x1F));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	e1000_write_vfta(hw, index, vfta);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	u32 vfta, index;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
		e1000_irq_disable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	if (!test_bit(__E1000_DOWN, &adapter->flags))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		e1000_irq_enable(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	/* remove VID from filter table */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	index = (vid >> 5) & 0x7F;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	vfta &= ~(1 << (vid & 0x1F));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	e1000_write_vfta(hw, index, vfta);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
static void e1000_restore_vlan(struct e1000_adapter *adapter)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
	if (adapter->vlgrp) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		u16 vid;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
			if (!vlan_group_get_device(adapter->vlgrp, vid))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
				continue;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	hw->autoneg = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	/* Fiber NICs only allow 1000 gbps Full duplex */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	if ((hw->media_type == e1000_media_type_fiber) &&
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		e_err("Unsupported Speed/Duplex configuration\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		return -EINVAL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	switch (spddplx) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	case SPEED_10 + DUPLEX_HALF:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		hw->forced_speed_duplex = e1000_10_half;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	case SPEED_10 + DUPLEX_FULL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		hw->forced_speed_duplex = e1000_10_full;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	case SPEED_100 + DUPLEX_HALF:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		hw->forced_speed_duplex = e1000_100_half;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	case SPEED_100 + DUPLEX_FULL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		hw->forced_speed_duplex = e1000_100_full;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	case SPEED_1000 + DUPLEX_FULL:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		hw->autoneg = 1;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		break;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	default:
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		e_err("Unsupported Speed/Duplex configuration\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		return -EINVAL;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	u32 ctrl, ctrl_ext, rctl, status;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	u32 wufc = adapter->wol;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
#ifdef CONFIG_PM
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	int retval = 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	netif_device_detach(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	if (netif_running(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		e1000_down(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
#ifdef CONFIG_PM
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	retval = pci_save_state(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	if (retval)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		return retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	status = er32(STATUS);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	if (status & E1000_STATUS_LU)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		wufc &= ~E1000_WUFC_LNKC;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	if (wufc) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		e1000_setup_rctl(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		e1000_set_rx_mode(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
		/* turn on all-multi mode if wake on multicast is enabled */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		if (wufc & E1000_WUFC_MC) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
			rctl = er32(RCTL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			rctl |= E1000_RCTL_MPE;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			ew32(RCTL, rctl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		if (hw->mac_type >= e1000_82540) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			ctrl = er32(CTRL);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			/* advertise wake from D3Cold */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			#define E1000_CTRL_ADVD3WUC 0x00100000
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
			/* phy power management enable */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
			ctrl |= E1000_CTRL_ADVD3WUC |
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
				E1000_CTRL_EN_PHY_PWR_MGMT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			ew32(CTRL, ctrl);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
		if (hw->media_type == e1000_media_type_fiber ||
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		    hw->media_type == e1000_media_type_internal_serdes) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			/* keep the laser running in D3 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
			ctrl_ext = er32(CTRL_EXT);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
			ew32(CTRL_EXT, ctrl_ext);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		ew32(WUC, E1000_WUC_PME_EN);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		ew32(WUFC, wufc);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		ew32(WUC, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		ew32(WUFC, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	e1000_release_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	*enable_wake = !!wufc;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	/* make sure adapter isn't asleep if manageability is enabled */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	if (adapter->en_mng_pt)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		*enable_wake = true;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		e1000_free_irq(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	pci_disable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
#ifdef CONFIG_PM
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	int retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	bool wake;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	retval = __e1000_shutdown(pdev, &wake);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	if (retval)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		return retval;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	if (wake) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
		pci_prepare_to_sleep(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	} else {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		pci_wake_from_d3(pdev, false);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
		pci_set_power_state(pdev, PCI_D3hot);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
static int e1000_resume(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	u32 err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	pci_set_power_state(pdev, PCI_D0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	pci_restore_state(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	pci_save_state(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	if (adapter->need_ioport)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		err = pci_enable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		err = pci_enable_device_mem(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		pr_err("Cannot enable PCI device from suspend\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	pci_set_master(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	pci_enable_wake(pdev, PCI_D3hot, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	pci_enable_wake(pdev, PCI_D3cold, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	if (netif_running(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
		err = e1000_request_irq(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		if (err)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			return err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	e1000_power_up_phy(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	ew32(WUS, ~0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	e1000_init_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		e1000_up(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	netif_device_attach(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	return 0;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
static void e1000_shutdown(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	bool wake;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	__e1000_shutdown(pdev, &wake);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	if (system_state == SYSTEM_POWER_OFF) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		pci_wake_from_d3(pdev, wake);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		pci_set_power_state(pdev, PCI_D3hot);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
#ifdef CONFIG_NET_POLL_CONTROLLER
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
/*
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
 * Polling 'interrupt' - used by things like netconsole to send skbs
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
 * without having to re-enable interrupts. It's not called while
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
 * the interrupt routine is executing.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
static void e1000_netpoll(struct net_device *netdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	disable_irq(adapter->pdev->irq);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	e1000_intr(adapter->pdev->irq, netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	enable_irq(adapter->pdev->irq);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
#endif
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
 * e1000_io_error_detected - called when PCI error is detected
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
 * @pdev: Pointer to PCI device
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
 * @state: The current pci connection state
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
 * This function is called after a PCI bus error affecting
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
 * this device has been detected.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
						pci_channel_state_t state)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	netif_device_detach(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	if (state == pci_channel_io_perm_failure)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
		return PCI_ERS_RESULT_DISCONNECT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	if (netif_running(netdev))
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		e1000_down(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	pci_disable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	/* Request a slot slot reset. */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	return PCI_ERS_RESULT_NEED_RESET;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
 * e1000_io_slot_reset - called after the pci bus has been reset.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
 * @pdev: Pointer to PCI device
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
 * Restart the card from scratch, as if from a cold-boot. Implementation
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
 * resembles the first-half of the e1000_resume routine.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	struct e1000_hw *hw = &adapter->hw;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	int err;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	if (adapter->need_ioport)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		err = pci_enable_device(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	else
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
		err = pci_enable_device_mem(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	if (err) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
		pr_err("Cannot re-enable PCI device after reset.\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
		return PCI_ERS_RESULT_DISCONNECT;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	pci_set_master(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	pci_enable_wake(pdev, PCI_D3hot, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	pci_enable_wake(pdev, PCI_D3cold, 0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	e1000_reset(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	ew32(WUS, ~0);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	return PCI_ERS_RESULT_RECOVERED;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
/**
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
 * e1000_io_resume - called when traffic can start flowing again.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
 * @pdev: Pointer to PCI device
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
 *
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
 * This callback is called when the error recovery driver tells us that
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
 * its OK to resume normal operation. Implementation resembles the
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
 * second-half of the e1000_resume routine.
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
 */
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
static void e1000_io_resume(struct pci_dev *pdev)
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
{
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	struct net_device *netdev = pci_get_drvdata(pdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	struct e1000_adapter *adapter = netdev_priv(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	e1000_init_manageability(adapter);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	if (netif_running(netdev)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		if (e1000_up(adapter)) {
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
			pr_info("can't bring device back up after reset\n");
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
			return;
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
		}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	netif_device_attach(netdev);
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
}
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
fda70486f179 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
/* e1000_main.c */