devices/e1000/e1000_main-2.6.32-orig.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2171 4eff8c9cfbbc
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2171
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k5-NAPI"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static struct pci_device_id e1000_pci_tbl[] = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
				    struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static int e1000_set_mac(struct net_device *netdev, void *p);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr(int irq, void *data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
				     struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
				     int *work_done, int work_to_do);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
				   struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				   int cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
					 struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
					 int cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			   int cmd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_tx_timeout(struct net_device *dev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_reset_task(struct work_struct *work);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_smartspeed(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
                                       struct sk_buff *skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_restore_vlan(struct e1000_adapter *adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_PM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static int e1000_resume(struct pci_dev *pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_shutdown(struct pci_dev *pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
#ifdef CONFIG_NET_POLL_CONTROLLER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
/* for netdump / net console */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_netpoll (struct net_device *netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#define COPYBREAK_DEFAULT 256
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
module_param(copybreak, uint, 0644);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
MODULE_PARM_DESC(copybreak,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	"Maximum size of packet that is copied to a new buffer on receive");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
                     pci_channel_state_t state);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_io_resume(struct pci_dev *pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static struct pci_error_handlers e1000_err_handler = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	.error_detected = e1000_io_error_detected,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	.slot_reset = e1000_io_slot_reset,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.resume = e1000_io_resume,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static struct pci_driver e1000_driver = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.name     = e1000_driver_name,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	.id_table = e1000_pci_tbl,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.probe    = e1000_probe,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.remove   = __devexit_p(e1000_remove),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#ifdef CONFIG_PM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	/* Power Managment Hooks */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.suspend  = e1000_suspend,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.resume   = e1000_resume,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.shutdown = e1000_shutdown,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.err_handler = &e1000_err_handler
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
MODULE_LICENSE("GPL");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
MODULE_VERSION(DRV_VERSION);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
module_param(debug, int, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 * e1000_init_module - Driver Registration Routine
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 * e1000_init_module is the first routine called when the driver is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 * loaded. All it does is register with the PCI subsystem.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
static int __init e1000_init_module(void)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	int ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	printk(KERN_INFO "%s - version %s\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	       e1000_driver_string, e1000_driver_version);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	printk(KERN_INFO "%s\n", e1000_copyright);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	ret = pci_register_driver(&e1000_driver);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	if (copybreak != COPYBREAK_DEFAULT) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
		if (copybreak == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
			printk(KERN_INFO "e1000: copybreak disabled\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
			printk(KERN_INFO "e1000: copybreak enabled for "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
			       "packets <= %u bytes\n", copybreak);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	return ret;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
module_init(e1000_init_module);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 * e1000_exit_module - Driver Exit Cleanup Routine
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
 * e1000_exit_module is called just before the driver is removed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
 * from memory.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
static void __exit e1000_exit_module(void)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	pci_unregister_driver(&e1000_driver);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
module_exit(e1000_exit_module);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
static int e1000_request_irq(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	irq_handler_t handler = e1000_intr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	int irq_flags = IRQF_SHARED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	int err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	                  netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		        "Unable to allocate interrupt Error: %d\n", err);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
static void e1000_free_irq(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	free_irq(adapter->pdev->irq, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
 * e1000_irq_disable - Mask off interrupt generation on the NIC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
static void e1000_irq_disable(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	ew32(IMC, ~0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	synchronize_irq(adapter->pdev->irq);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
 * e1000_irq_enable - Enable default interrupt generation settings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
static void e1000_irq_enable(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	ew32(IMS, IMS_ENABLE_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	u16 vid = hw->mng_cookie.vlan_id;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	u16 old_vid = adapter->mng_vlan_id;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	if (adapter->vlgrp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
			if (hw->mng_cookie.status &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
				e1000_vlan_rx_add_vid(netdev, vid);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
				adapter->mng_vlan_id = vid;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
			} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
					(vid != old_vid) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
				e1000_vlan_rx_kill_vid(netdev, old_vid);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		} else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
			adapter->mng_vlan_id = vid;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
static void e1000_init_manageability(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	if (adapter->en_mng_pt) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		u32 manc = er32(MANC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		/* disable hardware interception of ARP */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		manc &= ~(E1000_MANC_ARP_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		ew32(MANC, manc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
static void e1000_release_manageability(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	if (adapter->en_mng_pt) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		u32 manc = er32(MANC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		/* re-enable hardware interception of ARP */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		manc |= E1000_MANC_ARP_EN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
		ew32(MANC, manc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
 * e1000_configure - configure the hardware for RX and TX
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
 * @adapter = private board structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
static void e1000_configure(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	e1000_set_rx_mode(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	e1000_restore_vlan(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	e1000_init_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	e1000_configure_tx(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	e1000_setup_rctl(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	e1000_configure_rx(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	/* call E1000_DESC_UNUSED which always leaves
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	 * at least 1 descriptor unused to make sure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	 * next_to_use != next_to_clean */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	for (i = 0; i < adapter->num_rx_queues; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		adapter->alloc_rx_buf(adapter, ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		                      E1000_DESC_UNUSED(ring));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	adapter->tx_queue_len = netdev->tx_queue_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
int e1000_up(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	/* hardware has been reset, we need to reload some things */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	e1000_configure(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	clear_bit(__E1000_DOWN, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	napi_enable(&adapter->napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	netif_wake_queue(adapter->netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	/* fire a link change interrupt to start the watchdog */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	ew32(ICS, E1000_ICS_LSC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
 * e1000_power_up_phy - restore link in case the phy was powered down
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
 * @adapter: address of board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
 * The phy may be powered down to save power and turn off link when the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
 * driver is unloaded and wake on lan is not enabled (among others)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
 * *** this routine MUST be followed by a call to e1000_reset ***
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
void e1000_power_up_phy(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	u16 mii_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	/* Just clear the power down bit to wake the phy back up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		/* according to the manual, the phy will retain its
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		 * settings across a power-down/up cycle */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
		mii_reg &= ~MII_CR_POWER_DOWN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
static void e1000_power_down_phy(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	/* Power down the PHY so no link is implied when interface is down *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	 * The PHY cannot be powered down if any of the following is true *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	 * (a) WoL is enabled
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	 * (b) AMT is active
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 * (c) SoL/IDER session is active */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	   hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
		u16 mii_reg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
		case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
		case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
				goto out;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
			goto out;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		mii_reg |= MII_CR_POWER_DOWN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		mdelay(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
out:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
void e1000_down(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	u32 rctl, tctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	/* signal that we're down so the interrupt handler does not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	 * reschedule our watchdog timer */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	set_bit(__E1000_DOWN, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	/* disable receives in the hardware */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	/* flush and sleep below */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	netif_tx_disable(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	/* disable transmits in the hardware */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	tctl = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	tctl &= ~E1000_TCTL_EN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	ew32(TCTL, tctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	/* flush both disables and wait for them to finish */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	msleep(10);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	napi_disable(&adapter->napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	e1000_irq_disable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	del_timer_sync(&adapter->tx_fifo_stall_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	del_timer_sync(&adapter->watchdog_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	del_timer_sync(&adapter->phy_info_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	netdev->tx_queue_len = adapter->tx_queue_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	adapter->link_speed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	adapter->link_duplex = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	netif_carrier_off(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
	e1000_clean_all_tx_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	e1000_clean_all_rx_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
void e1000_reinit_locked(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	WARN_ON(in_interrupt());
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
void e1000_reset(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	bool legacy_pba_adjust = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	u16 hwm;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	/* Repartition Pba for greater than 9k mtu
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	 * To take effect CTRL.RST is required.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	case e1000_82540:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		legacy_pba_adjust = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
		pba = E1000_PBA_48K;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	case e1000_82545:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	case e1000_82545_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		pba = E1000_PBA_48K;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		legacy_pba_adjust = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		pba = E1000_PBA_30K;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	case e1000_undefined:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	case e1000_num_macs:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	if (legacy_pba_adjust) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
			pba -= 8; /* allocate more FIFO for Tx */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		if (hw->mac_type == e1000_82547) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
			adapter->tx_fifo_head = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
			adapter->tx_fifo_size =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
			atomic_set(&adapter->tx_fifo_stall, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		/* adjust PBA for jumbo frames */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		ew32(PBA, pba);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		/* To maintain wire speed transmits, the Tx FIFO should be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		 * large enough to accommodate two full transmit packets,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		 * the Rx FIFO should be large enough to accommodate at least
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		 * one full receive packet and is similarly rounded up and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
		 * expressed in KB. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		pba = er32(PBA);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		/* upper 16 bits has Tx packet buffer allocation size in KB */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		tx_space = pba >> 16;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		/* lower 16 bits has Rx packet buffer allocation size in KB */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		pba &= 0xffff;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		 * the tx fifo also stores 16 bytes of information about the tx
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		 * but don't include ethernet FCS because hardware appends it
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		min_tx_space = (hw->max_frame_size +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		                sizeof(struct e1000_tx_desc) -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		                ETH_FCS_LEN) * 2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		min_tx_space = ALIGN(min_tx_space, 1024);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		min_tx_space >>= 10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		/* software strips receive CRC, so leave room for it */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		min_rx_space = hw->max_frame_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		min_rx_space = ALIGN(min_rx_space, 1024);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		min_rx_space >>= 10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		/* If current Tx allocation is less than the min Tx FIFO size,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		 * and the min Tx FIFO size is less than the current Rx FIFO
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		 * allocation, take space away from current Rx allocation */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		if (tx_space < min_tx_space &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		    ((min_tx_space - tx_space) < pba)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
			pba = pba - (min_tx_space - tx_space);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
			/* PCI/PCIx hardware has PBA alignment constraints */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
			switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
			case e1000_82545 ... e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
				pba &= ~(E1000_PBA_8K - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
			/* if short on rx space, rx wins and must trump tx
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
			 * adjustment or use Early Receive if available */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
			if (pba < min_rx_space)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
				pba = min_rx_space;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	ew32(PBA, pba);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	 * flow control settings:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	 * The high water mark must be low enough to fit one full frame
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	 * (or the size used for early receive) above it in the Rx FIFO.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	 * Set it to the lower of:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	 * - 90% of the Rx FIFO size, and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	 * - the full Rx FIFO size minus the early receive size (for parts
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	 * - the full Rx FIFO size minus one full frame
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	hwm = min(((pba << 10) * 9 / 10),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		  ((pba << 10) - hw->max_frame_size));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	hw->fc_low_water = hw->fc_high_water - 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	hw->fc_send_xon = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	hw->fc = hw->original_fc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	/* Allow time for pending master requests to run */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	e1000_reset_hw(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	if (hw->mac_type >= e1000_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		ew32(WUC, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	if (e1000_init_hw(hw))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		DPRINTK(PROBE, ERR, "Hardware Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	e1000_update_mng_vlan(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	if (hw->mac_type >= e1000_82544 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	    hw->autoneg == 1 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		u32 ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		/* clear phy power management bit if we are in gig only mode,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		 * which if enabled will attempt negotiation to 100Mb, which
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		 * can cause a loss of link at power off or driver unload */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		ctrl &= ~E1000_CTRL_SWDPIN3;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	e1000_reset_adaptive(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	e1000_phy_get_info(hw, &adapter->phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	e1000_release_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
 *  Dump the eeprom for users having checksum issues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	struct ethtool_eeprom eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	const struct ethtool_ops *ops = netdev->ethtool_ops;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	u8 *data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	u16 csum_old, csum_new = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	eeprom.len = ops->get_eeprom_len(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	eeprom.offset = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	data = kmalloc(eeprom.len, GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	if (!data) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		       " data\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	ops->get_eeprom(netdev, &eeprom, data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		csum_new += data[i] + (data[i + 1] << 8);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	csum_new = EEPROM_SUM - csum_new;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	printk(KERN_ERR "/*********************/\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	printk(KERN_ERR "Offset    Values\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	printk(KERN_ERR "========  ======\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	printk(KERN_ERR "Include this output when contacting your support "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	       "provider.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	printk(KERN_ERR "This is not a software error! Something bad "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	       "happened to your hardware or\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	printk(KERN_ERR "EEPROM image. Ignoring this "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	       "problem could result in further problems,\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	       "which is invalid\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	printk(KERN_ERR "and requires you to set the proper MAC "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	       "address manually before continuing\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	printk(KERN_ERR "to enable this network device.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	       "to your hardware vendor\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	printk(KERN_ERR "or Intel Customer Support.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	printk(KERN_ERR "/*********************/\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	kfree(data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
 * @pdev: PCI device information struct
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
 * Return true if an adapter needs ioport resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
static int e1000_is_need_ioport(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	switch (pdev->device) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	case E1000_DEV_ID_82540EM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	case E1000_DEV_ID_82540EM_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	case E1000_DEV_ID_82540EP:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	case E1000_DEV_ID_82540EP_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	case E1000_DEV_ID_82540EP_LP:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	case E1000_DEV_ID_82541EI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	case E1000_DEV_ID_82541EI_MOBILE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	case E1000_DEV_ID_82541ER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	case E1000_DEV_ID_82541ER_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	case E1000_DEV_ID_82541GI:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	case E1000_DEV_ID_82541GI_LF:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	case E1000_DEV_ID_82541GI_MOBILE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	case E1000_DEV_ID_82544EI_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	case E1000_DEV_ID_82544EI_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	case E1000_DEV_ID_82544GC_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	case E1000_DEV_ID_82544GC_LOM:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	case E1000_DEV_ID_82545EM_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	case E1000_DEV_ID_82545EM_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	case E1000_DEV_ID_82546EB_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	case E1000_DEV_ID_82546EB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
static const struct net_device_ops e1000_netdev_ops = {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	.ndo_open		= e1000_open,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	.ndo_stop		= e1000_close,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	.ndo_start_xmit		= e1000_xmit_frame,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	.ndo_get_stats		= e1000_get_stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	.ndo_set_rx_mode	= e1000_set_rx_mode,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	.ndo_set_mac_address	= e1000_set_mac,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	.ndo_tx_timeout 	= e1000_tx_timeout,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	.ndo_change_mtu		= e1000_change_mtu,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	.ndo_do_ioctl		= e1000_ioctl,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	.ndo_validate_addr	= eth_validate_addr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
#ifdef CONFIG_NET_POLL_CONTROLLER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	.ndo_poll_controller	= e1000_netpoll,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
 * e1000_probe - Device Initialization Routine
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
 * @pdev: PCI device information struct
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
 * @ent: entry in e1000_pci_tbl
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
 * Returns 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
 * e1000_probe initializes an adapter identified by a pci_dev structure.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 * The OS initialization, configuring of the adapter private structure,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 * and a hardware reset occur.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
static int __devinit e1000_probe(struct pci_dev *pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
				 const struct pci_device_id *ent)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	struct net_device *netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	struct e1000_adapter *adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct e1000_hw *hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	static int cards_found = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	int i, err, pci_using_dac;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	u16 eeprom_data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	int bars, need_ioport;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	/* do not allocate ioport bars when not needed */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	need_ioport = e1000_is_need_ioport(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	if (need_ioport) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		err = pci_enable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		err = pci_enable_device_mem(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		pci_using_dac = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
			if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
				E1000_ERR("No usable DMA configuration, "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
					  "aborting\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
				goto err_dma;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		pci_using_dac = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		goto err_pci_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	pci_set_master(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	err = -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	if (!netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		goto err_alloc_etherdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	SET_NETDEV_DEV(netdev, &pdev->dev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	pci_set_drvdata(pdev, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	adapter->netdev = netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	adapter->pdev = pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	adapter->msg_enable = (1 << debug) - 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	adapter->bars = bars;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	adapter->need_ioport = need_ioport;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	hw->back = adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	err = -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	if (!hw->hw_addr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		goto err_ioremap;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	if (adapter->need_ioport) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		for (i = BAR_1; i <= BAR_5; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
			if (pci_resource_len(pdev, i) == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
				continue;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
				hw->io_base = pci_resource_start(pdev, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	netdev->netdev_ops = &e1000_netdev_ops;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	e1000_set_ethtool_ops(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	netdev->watchdog_timeo = 5 * HZ;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	adapter->bd_number = cards_found;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	/* setup the private structure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	err = e1000_sw_init(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		goto err_sw_init;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	err = -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	if (hw->mac_type >= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		netdev->features = NETIF_F_SG |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
				   NETIF_F_HW_CSUM |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
				   NETIF_F_HW_VLAN_TX |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
				   NETIF_F_HW_VLAN_RX |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
				   NETIF_F_HW_VLAN_FILTER;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	if ((hw->mac_type >= e1000_82544) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	   (hw->mac_type != e1000_82547))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		netdev->features |= NETIF_F_TSO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	if (pci_using_dac)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		netdev->features |= NETIF_F_HIGHDMA;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	netdev->vlan_features |= NETIF_F_TSO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	netdev->vlan_features |= NETIF_F_HW_CSUM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	netdev->vlan_features |= NETIF_F_SG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	/* initialize eeprom parameters */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	if (e1000_init_eeprom_params(hw)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		E1000_ERR("EEPROM initialization failed\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
		goto err_eeprom;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	/* before reading the EEPROM, reset the controller to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	 * put the device in a known good starting state */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	e1000_reset_hw(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	/* make sure the EEPROM is good */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	if (e1000_validate_eeprom_checksum(hw) < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		e1000_dump_eeprom(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		 * set MAC address to all zeroes to invalidate and temporary
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		 * disable this device for the user. This blocks regular
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		 * traffic while still permitting ethtool ioctls from reaching
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		 * the hardware as well as allowing the user to run the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		 * interface after manually setting a hw addr using
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		 * `ip set address`
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		memset(hw->mac_addr, 0, netdev->addr_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		/* copy the MAC address out of the EEPROM */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		if (e1000_read_mac_addr(hw))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	/* don't block initalization here due to bad MAC address */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	if (!is_valid_ether_addr(netdev->perm_addr))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	e1000_get_bus_info(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	init_timer(&adapter->tx_fifo_stall_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	init_timer(&adapter->watchdog_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	adapter->watchdog_timer.function = &e1000_watchdog;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	adapter->watchdog_timer.data = (unsigned long) adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	init_timer(&adapter->phy_info_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	adapter->phy_info_timer.function = &e1000_update_phy_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	adapter->phy_info_timer.data = (unsigned long)adapter;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	e1000_check_options(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	/* Initial Wake on LAN setting
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	 * If APM wake is enabled in the EEPROM,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	 * enable the ACPI Magic Packet filter
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	case e1000_82543:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		e1000_read_eeprom(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	case e1000_82546:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	case e1000_82546_rev_3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
			e1000_read_eeprom(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		/* Fall Through */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		e1000_read_eeprom(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	if (eeprom_data & eeprom_apme_mask)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		adapter->eeprom_wol |= E1000_WUFC_MAG;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	/* now that we have the eeprom settings, apply the special cases
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	 * where the eeprom may be wrong or the board simply won't support
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	 * wake on lan on a particular port */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	switch (pdev->device) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	case E1000_DEV_ID_82546GB_PCIE:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		adapter->eeprom_wol = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	case E1000_DEV_ID_82546EB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	case E1000_DEV_ID_82546GB_FIBER:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		/* Wake events only supported on port A for dual fiber
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		 * regardless of eeprom setting */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
			adapter->eeprom_wol = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		/* if quad port adapter, disable WoL on all but port A */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		if (global_quad_port_a != 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
			adapter->eeprom_wol = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
			adapter->quad_port_a = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		/* Reset for multiple quad port adapters */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		if (++global_quad_port_a == 4)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
			global_quad_port_a = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	/* initialize the wol settings based on the eeprom settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	adapter->wol = adapter->eeprom_wol;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	/* print bus type/speed/width info */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		((hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" : "32-bit"));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	printk("%pM\n", netdev->dev_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	/* reset the hardware with the new settings */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	strcpy(netdev->name, "eth%d");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	err = register_netdev(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		goto err_register;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	/* carrier off reporting is important to ethtool even BEFORE open */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	netif_carrier_off(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	cards_found++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
err_register:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
err_eeprom:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	e1000_phy_hw_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	if (hw->flash_address)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		iounmap(hw->flash_address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	kfree(adapter->tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	kfree(adapter->rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
err_sw_init:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	iounmap(hw->hw_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
err_ioremap:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	free_netdev(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
err_alloc_etherdev:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	pci_release_selected_regions(pdev, bars);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
err_pci_reg:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
err_dma:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	pci_disable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
 * e1000_remove - Device Removal Routine
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
 * @pdev: PCI device information struct
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
 * e1000_remove is called by the PCI subsystem to alert the driver
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
 * that it should release a PCI device.  The could be caused by a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
 * Hot-Plug event, or because the driver is going to be removed from
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
 * memory.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
static void __devexit e1000_remove(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	set_bit(__E1000_DOWN, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	del_timer_sync(&adapter->tx_fifo_stall_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	del_timer_sync(&adapter->watchdog_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	del_timer_sync(&adapter->phy_info_timer);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	cancel_work_sync(&adapter->reset_task);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	e1000_release_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	unregister_netdev(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	e1000_phy_hw_reset(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	kfree(adapter->tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	kfree(adapter->rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	iounmap(hw->hw_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	if (hw->flash_address)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		iounmap(hw->flash_address);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	pci_release_selected_regions(pdev, adapter->bars);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	free_netdev(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	pci_disable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
 * @adapter: board private structure to initialize
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
 * e1000_sw_init initializes the Adapter private data structure.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
 * Fields are initialized based on PCI device information and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
 * OS network device settings (MTU size).
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	/* PCI config space info */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	hw->vendor_id = pdev->vendor;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	hw->device_id = pdev->device;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	hw->subsystem_id = pdev->subsystem_device;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	hw->revision_id = pdev->revision;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	hw->max_frame_size = netdev->mtu +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	/* identify the MAC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	if (e1000_set_mac_type(hw)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		return -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	case e1000_82541:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	case e1000_82547:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	case e1000_82541_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	case e1000_82547_rev_2:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		hw->phy_init_script = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	e1000_set_media_type(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	hw->wait_autoneg_complete = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	hw->tbi_compatibility_en = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	hw->adaptive_ifs = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	/* Copper options */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		hw->mdix = AUTO_ALL_MODES;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		hw->disable_polarity_correction = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		hw->master_slave = E1000_MASTER_SLAVE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	adapter->num_tx_queues = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	adapter->num_rx_queues = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	if (e1000_alloc_queues(adapter)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	/* Explicitly disable IRQ since the NIC can be in any state. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	e1000_irq_disable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	spin_lock_init(&adapter->stats_lock);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	set_bit(__E1000_DOWN, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
 * e1000_alloc_queues - Allocate memory for all rings
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
 * @adapter: board private structure to initialize
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
 * We allocate one ring per queue at run-time since we don't know the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
 * number of queues at compile-time.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	if (!adapter->tx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	if (!adapter->rx_ring) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		kfree(adapter->tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
 * e1000_open - Called when a network interface is made active
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
 * Returns 0 on success, negative value on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
 * The open entry point is called when a network interface is made
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
 * active by the system (IFF_UP).  At this point all resources needed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
 * for transmit and receive operations are allocated, the interrupt
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
 * handler is registered with the OS, the watchdog timer is started,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
 * and the stack is notified that the interface is ready.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
static int e1000_open(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	int err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	/* disallow open during test */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	if (test_bit(__E1000_TESTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
		return -EBUSY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	netif_carrier_off(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	/* allocate transmit descriptors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	err = e1000_setup_all_tx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
		goto err_setup_tx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	/* allocate receive descriptors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	err = e1000_setup_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		goto err_setup_rx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	e1000_power_up_phy(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	if ((hw->mng_cookie.status &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		e1000_update_mng_vlan(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	/* before we allocate an interrupt, we must be ready to handle it.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	 * as soon as we call pci_request_irq, so we have to setup our
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	 * clean_rx handler before we do so.  */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	e1000_configure(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	err = e1000_request_irq(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		goto err_req_irq;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	/* From here on the code is the same as e1000_up() */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	clear_bit(__E1000_DOWN, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	napi_enable(&adapter->napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	netif_start_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	/* fire a link status change interrupt to start the watchdog */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	ew32(ICS, E1000_ICS_LSC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
err_req_irq:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	e1000_power_down_phy(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	e1000_free_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
err_setup_rx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	e1000_free_all_tx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
err_setup_tx:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
 * e1000_close - Disables a network interface
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 * Returns 0, this is not allowed to fail
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 * The close entry point is called when an interface is de-activated
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 * by the OS.  The hardware is still under the drivers control, but
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * needs to be disabled.  A global MAC reset is issued to stop the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 * hardware, and all transmit and receive resources are freed.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
static int e1000_close(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	e1000_power_down_phy(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	e1000_free_irq(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	e1000_free_all_tx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	e1000_free_all_rx_resources(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	/* kill manageability vlan ID if supported, but not if a vlan with
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	 * the same ID is registered on the host OS (let 8021q kill it) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	if ((hw->mng_cookie.status &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	     !(adapter->vlgrp &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
 * @adapter: address of board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 * @start: address of beginning of memory
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 * @len: length of memory
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
				  unsigned long len)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	unsigned long begin = (unsigned long)start;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	unsigned long end = begin + len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	/* First rev 82545 and 82546 need to not allow any memory
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	 * write location to cross 64k boundary due to errata 23 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	if (hw->mac_type == e1000_82545 ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	    hw->mac_type == e1000_82546) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * @txdr:    tx descriptor ring (for a specific queue) to setup
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 * Return 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
				    struct e1000_tx_ring *txdr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	int size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	size = sizeof(struct e1000_buffer) * txdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	txdr->buffer_info = vmalloc(size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	if (!txdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		"Unable to allocate memory for the transmit descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	memset(txdr->buffer_info, 0, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	/* round up to nearest 4K */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	txdr->size = ALIGN(txdr->size, 4096);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	if (!txdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
setup_tx_desc_die:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		vfree(txdr->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		"Unable to allocate memory for the transmit descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	/* Fix for errata 23, can't cross 64kB boundary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		void *olddesc = txdr->desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		dma_addr_t olddma = txdr->dma;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
				     "at %p\n", txdr->size, txdr->desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		/* Try again, without freeing the previous */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		/* Failed allocation, critical failure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		if (!txdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
			goto setup_tx_desc_die;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
			/* give up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
			pci_free_consistent(pdev, txdr->size, txdr->desc,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
					    txdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
				"Unable to allocate aligned memory "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
				"for the transmit descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
			vfree(txdr->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			/* Free old allocation, new allocation was successful */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	memset(txdr->desc, 0, txdr->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	txdr->next_to_use = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	txdr->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * 				  (Descriptors) for all queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 * Return 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	int i, err = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	for (i = 0; i < adapter->num_tx_queues; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
		if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
			DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
				"Allocation for Tx Queue %u failed\n", i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
			for (i-- ; i >= 0; i--)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
				e1000_free_tx_resources(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
							&adapter->tx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
 * Configure the Tx unit of the MAC after a reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
static void e1000_configure_tx(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	u64 tdba;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	u32 tdlen, tctl, tipg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	u32 ipgr1, ipgr2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	/* Setup the HW Tx Head and Tail descriptor pointers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	switch (adapter->num_tx_queues) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	case 1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
		tdba = adapter->tx_ring[0].dma;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
		tdlen = adapter->tx_ring[0].count *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
			sizeof(struct e1000_tx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		ew32(TDLEN, tdlen);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		ew32(TDBAH, (tdba >> 32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		ew32(TDT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		ew32(TDH, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	/* Set the default values for the Tx Inter Packet Gap timer */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	if ((hw->media_type == e1000_media_type_fiber ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	     hw->media_type == e1000_media_type_internal_serdes))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	case e1000_82542_rev2_0:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	case e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		tipg = DEFAULT_82542_TIPG_IPGT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	ew32(TIPG, tipg);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	/* Set the Tx Interrupt Delay register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	ew32(TIDV, adapter->tx_int_delay);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	if (hw->mac_type >= e1000_82540)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		ew32(TADV, adapter->tx_abs_int_delay);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	/* Program the Transmit Control Register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	tctl = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	tctl &= ~E1000_TCTL_CT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	e1000_config_collision_dist(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	/* Setup Transmit Descriptor Settings for eop descriptor */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	/* only set IDE if we are delaying interrupts using the timers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	if (adapter->tx_int_delay)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	if (hw->mac_type < e1000_82543)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	/* Cache if we're 82544 running in PCI-X because we'll
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	 * need this to apply a workaround later in the send path. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	if (hw->mac_type == e1000_82544 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	    hw->bus_type == e1000_bus_type_pcix)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		adapter->pcix_82544 = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	ew32(TCTL, tctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
 * Returns 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
				    struct e1000_rx_ring *rxdr)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	int size, desc_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	size = sizeof(struct e1000_buffer) * rxdr->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	rxdr->buffer_info = vmalloc(size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
	if (!rxdr->buffer_info) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		"Unable to allocate memory for the receive descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	memset(rxdr->buffer_info, 0, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	desc_len = sizeof(struct e1000_rx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	/* Round up to nearest 4K */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	rxdr->size = rxdr->count * desc_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	rxdr->size = ALIGN(rxdr->size, 4096);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	if (!rxdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		"Unable to allocate memory for the receive descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
setup_rx_desc_die:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		vfree(rxdr->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		return -ENOMEM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	/* Fix for errata 23, can't cross 64kB boundary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		void *olddesc = rxdr->desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		dma_addr_t olddma = rxdr->dma;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
				     "at %p\n", rxdr->size, rxdr->desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		/* Try again, without freeing the previous */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		/* Failed allocation, critical failure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		if (!rxdr->desc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
			DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
				"Unable to allocate memory "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
				"for the receive descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
			goto setup_rx_desc_die;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
			/* give up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
					    rxdr->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
			DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
				"Unable to allocate aligned memory "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
				"for the receive descriptor ring\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
			goto setup_rx_desc_die;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
			/* Free old allocation, new allocation was successful */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	memset(rxdr->desc, 0, rxdr->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	rxdr->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	rxdr->next_to_use = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	rxdr->rx_skb_top = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
 * 				  (Descriptors) for all queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * Return 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	int i, err = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	for (i = 0; i < adapter->num_rx_queues; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
			DPRINTK(PROBE, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
				"Allocation for Rx Queue %u failed\n", i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
			for (i-- ; i >= 0; i--)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
				e1000_free_rx_resources(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
							&adapter->rx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
 * e1000_setup_rctl - configure the receive control registers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
 * @adapter: Board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
static void e1000_setup_rctl(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	if (hw->tbi_compatibility_on == 1)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		rctl |= E1000_RCTL_SBP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		rctl &= ~E1000_RCTL_SBP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		rctl &= ~E1000_RCTL_LPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		rctl |= E1000_RCTL_LPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	/* Setup buffer sizes */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	rctl &= ~E1000_RCTL_SZ_4096;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	rctl |= E1000_RCTL_BSEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	switch (adapter->rx_buffer_len) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		case E1000_RXBUFFER_2048:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
			rctl |= E1000_RCTL_SZ_2048;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
			rctl &= ~E1000_RCTL_BSEX;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		case E1000_RXBUFFER_4096:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
			rctl |= E1000_RCTL_SZ_4096;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		case E1000_RXBUFFER_8192:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			rctl |= E1000_RCTL_SZ_8192;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		case E1000_RXBUFFER_16384:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			rctl |= E1000_RCTL_SZ_16384;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
 * Configure the Rx unit of the MAC after a reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
static void e1000_configure_rx(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	u64 rdba;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	u32 rdlen, rctl, rxcsum;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		rdlen = adapter->rx_ring[0].count *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		        sizeof(struct e1000_rx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		rdlen = adapter->rx_ring[0].count *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		        sizeof(struct e1000_rx_desc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		adapter->clean_rx = e1000_clean_rx_irq;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	/* disable receives while setting up the descriptors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	/* set the Receive Delay Timer Register */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	ew32(RDTR, adapter->rx_int_delay);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	if (hw->mac_type >= e1000_82540) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		ew32(RADV, adapter->rx_abs_int_delay);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		if (adapter->itr_setting != 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			ew32(ITR, 1000000000 / (adapter->itr * 256));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	 * the Base and Length of the Rx Descriptor Ring */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	switch (adapter->num_rx_queues) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	case 1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		rdba = adapter->rx_ring[0].dma;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		ew32(RDLEN, rdlen);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		ew32(RDBAH, (rdba >> 32));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		ew32(RDT, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		ew32(RDH, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	if (hw->mac_type >= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		rxcsum = er32(RXCSUM);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		if (adapter->rx_csum)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
			rxcsum |= E1000_RXCSUM_TUOFL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
			/* don't need to clear IPPCSE as it defaults to 0 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
			rxcsum &= ~E1000_RXCSUM_TUOFL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		ew32(RXCSUM, rxcsum);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	/* Enable Receives */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
 * e1000_free_tx_resources - Free Tx Resources per Queue
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
 * @tx_ring: Tx descriptor ring for a specific queue
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 * Free all transmit software resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
				    struct e1000_tx_ring *tx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	e1000_clean_tx_ring(adapter, tx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	vfree(tx_ring->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	tx_ring->buffer_info = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	tx_ring->desc = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
 * Free all transmit software resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	for (i = 0; i < adapter->num_tx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
					     struct e1000_buffer *buffer_info)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	buffer_info->dma = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	if (buffer_info->skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		              DMA_TO_DEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		dev_kfree_skb_any(buffer_info->skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		buffer_info->skb = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	buffer_info->time_stamp = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	/* buffer_info must be completely set up in the transmit path */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
 * e1000_clean_tx_ring - Free Tx Buffers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
 * @tx_ring: ring to be cleaned
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
				struct e1000_tx_ring *tx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	unsigned long size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	/* Free all the Tx ring sk_buffs */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	for (i = 0; i < tx_ring->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	size = sizeof(struct e1000_buffer) * tx_ring->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	memset(tx_ring->buffer_info, 0, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	/* Zero out the descriptor ring */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	memset(tx_ring->desc, 0, tx_ring->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	tx_ring->next_to_use = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	tx_ring->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	tx_ring->last_tx_tso = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	writel(0, hw->hw_addr + tx_ring->tdh);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	writel(0, hw->hw_addr + tx_ring->tdt);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	for (i = 0; i < adapter->num_tx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
 * e1000_free_rx_resources - Free Rx Resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
 * @rx_ring: ring to clean the resources from
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
 * Free all receive software resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
				    struct e1000_rx_ring *rx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	e1000_clean_rx_ring(adapter, rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	vfree(rx_ring->buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	rx_ring->buffer_info = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	rx_ring->desc = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
 * Free all receive software resources
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	for (i = 0; i < adapter->num_rx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
 * @rx_ring: ring to free buffers from
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
				struct e1000_rx_ring *rx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	unsigned long size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	/* Free all the Rx ring sk_buffs */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	for (i = 0; i < rx_ring->count; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		if (buffer_info->dma &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		    adapter->clean_rx == e1000_clean_rx_irq) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
			pci_unmap_single(pdev, buffer_info->dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
			                 buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
			                 PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
		} else if (buffer_info->dma &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
			pci_unmap_page(pdev, buffer_info->dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			               buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
			               PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		buffer_info->dma = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		if (buffer_info->page) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			put_page(buffer_info->page);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			buffer_info->page = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
		if (buffer_info->skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
			dev_kfree_skb(buffer_info->skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			buffer_info->skb = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	/* there also may be some cached data from a chained receive */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	if (rx_ring->rx_skb_top) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		dev_kfree_skb(rx_ring->rx_skb_top);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		rx_ring->rx_skb_top = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	size = sizeof(struct e1000_buffer) * rx_ring->count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	memset(rx_ring->buffer_info, 0, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	/* Zero out the descriptor ring */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	memset(rx_ring->desc, 0, rx_ring->size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	rx_ring->next_to_clean = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	rx_ring->next_to_use = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	writel(0, hw->hw_addr + rx_ring->rdh);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	writel(0, hw->hw_addr + rx_ring->rdt);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	for (i = 0; i < adapter->num_rx_queues; i++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 * and memory write and invalidate disabled for certain operations
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	e1000_pci_clear_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	rctl |= E1000_RCTL_RST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	mdelay(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		e1000_clean_all_rx_rings(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	rctl &= ~E1000_RCTL_RST;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	mdelay(5);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		e1000_pci_set_mwi(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	if (netif_running(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		/* No need to loop, because 82542 supports only 1 queue */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
		e1000_configure_rx(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 * e1000_set_mac - Change the Ethernet Address of the NIC
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 * @p: pointer to an address structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
 * Returns 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
static int e1000_set_mac(struct net_device *netdev, void *p)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	struct sockaddr *addr = p;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	if (!is_valid_ether_addr(addr->sa_data))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
		return -EADDRNOTAVAIL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	/* 82542 2.0 needs to be in reset to write receive address registers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		e1000_enter_82542_rst(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	e1000_rar_set(hw, hw->mac_addr, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		e1000_leave_82542_rst(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
 * The set_rx_mode entry point is called whenever the unicast or multicast
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
 * address lists or the network interface flags are updated. This routine is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
 * responsible for configuring the hardware for proper unicast, multicast,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
 * promiscuous mode, and all-multi behavior.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
static void e1000_set_rx_mode(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	struct netdev_hw_addr *ha;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	bool use_uc = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	struct dev_addr_list *mc_ptr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	u32 rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	u32 hash_value;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	int i, rar_entries = E1000_RAR_ENTRIES;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	if (!mcarray) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		DPRINTK(PROBE, ERR, "memory allocation failed\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	/* Check for Promiscuous and All Multicast modes */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	if (netdev->flags & IFF_PROMISC) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		rctl &= ~E1000_RCTL_VFE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		if (netdev->flags & IFF_ALLMULTI)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
			rctl |= E1000_RCTL_MPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			rctl &= ~E1000_RCTL_MPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		/* Enable VLAN filter if there is a VLAN */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		if (adapter->vlgrp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
			rctl |= E1000_RCTL_VFE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	if (netdev->uc.count > rar_entries - 1) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		rctl |= E1000_RCTL_UPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	} else if (!(netdev->flags & IFF_PROMISC)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
		rctl &= ~E1000_RCTL_UPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		use_uc = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	/* 82542 2.0 needs to be in reset to write receive address registers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		e1000_enter_82542_rst(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	/* load the first 14 addresses into the exact filters 1-14. Unicast
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	 * addresses take precedence to avoid disabling unicast filtering
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	 * when possible.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	 * RAR 0 is used for the station MAC adddress
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	 * if there are not 14 addresses, go ahead and clear the filters
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
	i = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	if (use_uc)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		list_for_each_entry(ha, &netdev->uc.list, list) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			if (i == rar_entries)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
			e1000_rar_set(hw, ha->addr, i++);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	WARN_ON(i == rar_entries);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	mc_ptr = netdev->mc_list;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	for (; i < rar_entries; i++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
		if (mc_ptr) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			e1000_rar_set(hw, mc_ptr->da_addr, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			mc_ptr = mc_ptr->next;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
			E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	/* load any remaining addresses into the hash table */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
		u32 hash_reg, hash_bit, mta;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		hash_reg = (hash_value >> 5) & 0x7F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		hash_bit = hash_value & 0x1F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		mta = (1 << hash_bit);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		mcarray[hash_reg] |= mta;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	/* write the hash table completely, write from bottom to avoid
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	 * both stupid write combining chipsets, and flushing each write */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
		 * If we are on an 82544 has an errata where writing odd
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		 * offsets overwrites the previous even offset, but writing
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		 * backwards over the range solves the issue by always
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
		 * writing the odd offset first
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	if (hw->mac_type == e1000_82542_rev2_0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		e1000_leave_82542_rst(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	kfree(mcarray);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
/* Need to wait a few seconds after link up to get diagnostic information from
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
 * the phy */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
static void e1000_update_phy_info(unsigned long data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	e1000_phy_get_info(hw, &adapter->phy_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
 * e1000_82547_tx_fifo_stall - Timer Call-back
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
 * @data: pointer to adapter cast into an unsigned long
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
static void e1000_82547_tx_fifo_stall(unsigned long data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	u32 tctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	if (atomic_read(&adapter->tx_fifo_stall)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		if ((er32(TDT) == er32(TDH)) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
		   (er32(TDFT) == er32(TDFH)) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		   (er32(TDFTS) == er32(TDFHS))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			tctl = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
			ew32(TDFT, adapter->tx_head_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
			ew32(TDFH, adapter->tx_head_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
			ew32(TDFTS, adapter->tx_head_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
			ew32(TDFHS, adapter->tx_head_addr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
			ew32(TCTL, tctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
			E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			adapter->tx_fifo_head = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			atomic_set(&adapter->tx_fifo_stall, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			netif_wake_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
static bool e1000_has_link(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	bool link_active = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	/* get_link_status is set on LSC (link status) interrupt or
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	 * rx sequence error interrupt.  get_link_status will stay
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	 * false until the e1000_check_for_link establishes link
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	 * for copper adapters ONLY
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	switch (hw->media_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	case e1000_media_type_copper:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
		if (hw->get_link_status) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
			e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
			link_active = !hw->get_link_status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
			link_active = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	case e1000_media_type_fiber:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	case e1000_media_type_internal_serdes:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
		e1000_check_for_link(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		link_active = hw->serdes_has_link;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	return link_active;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
 * e1000_watchdog - Timer Call-back
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
 * @data: pointer to adapter cast into an unsigned long
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
static void e1000_watchdog(unsigned long data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	struct e1000_tx_ring *txdr = adapter->tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	u32 link, tctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	link = e1000_has_link(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	if ((netif_carrier_ok(netdev)) && link)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		goto link_up;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	if (link) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
		if (!netif_carrier_ok(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
			u32 ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
			bool txb2b = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
			/* update snapshot of PHY registers on LSC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
			e1000_get_speed_and_duplex(hw,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
			                           &adapter->link_speed,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
			                           &adapter->link_duplex);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
			ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
			printk(KERN_INFO "e1000: %s NIC Link is Up %d Mbps %s, "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
			       "Flow Control: %s\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			       netdev->name,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
			       adapter->link_speed,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
			       adapter->link_duplex == FULL_DUPLEX ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			        "Full Duplex" : "Half Duplex",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			/* tweak tx_queue_len according to speed/duplex
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
			 * and adjust the timeout factor */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
			netdev->tx_queue_len = adapter->tx_queue_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			adapter->tx_timeout_factor = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
			switch (adapter->link_speed) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			case SPEED_10:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
				txb2b = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
				netdev->tx_queue_len = 10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
				adapter->tx_timeout_factor = 16;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
			case SPEED_100:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
				txb2b = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
				netdev->tx_queue_len = 100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
				/* maybe add some timeout factor ? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			/* enable transmits in the hardware */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			tctl = er32(TCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
			tctl |= E1000_TCTL_EN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
			ew32(TCTL, tctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
			netif_carrier_on(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
			if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
				mod_timer(&adapter->phy_info_timer,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
				          round_jiffies(jiffies + 2 * HZ));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
			adapter->smartspeed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		if (netif_carrier_ok(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
			adapter->link_speed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
			adapter->link_duplex = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			printk(KERN_INFO "e1000: %s NIC Link is Down\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
			       netdev->name);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
			netif_carrier_off(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
			if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
				mod_timer(&adapter->phy_info_timer,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
				          round_jiffies(jiffies + 2 * HZ));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		e1000_smartspeed(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
link_up:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	e1000_update_stats(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	adapter->tpt_old = adapter->stats.tpt;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	adapter->colc_old = adapter->stats.colc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	adapter->gorcl_old = adapter->stats.gorcl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	adapter->gotcl_old = adapter->stats.gotcl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	e1000_update_adaptive(hw);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	if (!netif_carrier_ok(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
			/* We've lost link, so the controller stops DMA,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			 * but we've got queued Tx work that's never going
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			 * to get done, so reset controller to flush Tx.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			 * (Do the reset outside of interrupt context). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			adapter->tx_timeout_count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			schedule_work(&adapter->reset_task);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			/* return immediately since reset is imminent */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	/* Cause software interrupt to ensure rx ring is cleaned */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	ew32(ICS, E1000_ICS_RXDMT0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	/* Force detection of hung controller every watchdog period */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	adapter->detect_tx_hung = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	/* Reset the timer */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
		mod_timer(&adapter->watchdog_timer,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		          round_jiffies(jiffies + 2 * HZ));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
enum latency_range {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	lowest_latency = 0,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	low_latency = 1,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	bulk_latency = 2,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	latency_invalid = 255
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
};
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
 * e1000_update_itr - update the dynamic ITR value based on statistics
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
 * @adapter: pointer to adapter
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
 * @itr_setting: current adapter->itr
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
 * @packets: the number of packets during this measurement interval
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 * @bytes: the number of bytes during this measurement interval
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
 *      Stores a new ITR value based on packets and byte
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 *      counts during the last interrupt.  The advantage of per interrupt
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
 *      computation is faster updates and more accurate ITR for the current
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
 *      traffic pattern.  Constants in this function were computed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
 *      based on theoretical maximum wire speed and thresholds were set based
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
 *      on testing data as well as attempting to minimize response time
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
 *      while increasing bulk throughput.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
 *      this functionality is controlled by the InterruptThrottleRate module
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
 *      parameter (see e1000_param.c)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
				     u16 itr_setting, int packets, int bytes)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	unsigned int retval = itr_setting;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	if (unlikely(hw->mac_type < e1000_82540))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		goto update_itr_done;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	if (packets == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
		goto update_itr_done;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	switch (itr_setting) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	case lowest_latency:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		/* jumbo frames get bulk treatment*/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		if (bytes/packets > 8000)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			retval = bulk_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
		else if ((packets < 5) && (bytes > 512))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
			retval = low_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	case low_latency:  /* 50 usec aka 20000 ints/s */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
		if (bytes > 10000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
			/* jumbo frames need bulk latency setting */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			if (bytes/packets > 8000)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				retval = bulk_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
			else if ((packets < 10) || ((bytes/packets) > 1200))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
				retval = bulk_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
			else if ((packets > 35))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
				retval = lowest_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		} else if (bytes/packets > 2000)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
			retval = bulk_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		else if (packets <= 2 && bytes < 512)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			retval = lowest_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	case bulk_latency: /* 250 usec aka 4000 ints/s */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		if (bytes > 25000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
			if (packets > 35)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
				retval = low_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		} else if (bytes < 6000) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			retval = low_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
update_itr_done:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
static void e1000_set_itr(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	u16 current_itr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	u32 new_itr = adapter->itr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	if (unlikely(hw->mac_type < e1000_82540))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	if (unlikely(adapter->link_speed != SPEED_1000)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		current_itr = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
		new_itr = 4000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
		goto set_itr_now;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	adapter->tx_itr = e1000_update_itr(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	                            adapter->tx_itr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	                            adapter->total_tx_packets,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	                            adapter->total_tx_bytes);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		adapter->tx_itr = low_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	adapter->rx_itr = e1000_update_itr(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	                            adapter->rx_itr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	                            adapter->total_rx_packets,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	                            adapter->total_rx_bytes);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		adapter->rx_itr = low_latency;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	switch (current_itr) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	/* counts and packets in update_itr are dependent on these numbers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	case lowest_latency:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		new_itr = 70000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
	case low_latency:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		new_itr = 20000; /* aka hwitr = ~200 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	case bulk_latency:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		new_itr = 4000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
set_itr_now:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	if (new_itr != adapter->itr) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		/* this attempts to bias the interrupt rate towards Bulk
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
		 * by adding intermediate steps when interrupt rate is
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		 * increasing */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		new_itr = new_itr > adapter->itr ?
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		             min(adapter->itr + (new_itr >> 2), new_itr) :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		             new_itr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		adapter->itr = new_itr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		ew32(ITR, 1000000000 / (new_itr * 256));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
#define E1000_TX_FLAGS_CSUM		0x00000001
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
#define E1000_TX_FLAGS_VLAN		0x00000002
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
#define E1000_TX_FLAGS_TSO		0x00000004
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
#define E1000_TX_FLAGS_IPV4		0x00000008
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
#define E1000_TX_FLAGS_VLAN_SHIFT	16
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
static int e1000_tso(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	struct e1000_context_desc *context_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	u32 cmd_length = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	u16 ipcse = 0, tucse, mss;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	int err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	if (skb_is_gso(skb)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		if (skb_header_cloned(skb)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
				return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
		mss = skb_shinfo(skb)->gso_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
		if (skb->protocol == htons(ETH_P_IP)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
			struct iphdr *iph = ip_hdr(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
			iph->tot_len = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
			iph->check = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
								 iph->daddr, 0,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
								 IPPROTO_TCP,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
								 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
			cmd_length = E1000_TXD_CMD_IP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			ipcse = skb_transport_offset(skb) - 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
			ipv6_hdr(skb)->payload_len = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
			tcp_hdr(skb)->check =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
						 &ipv6_hdr(skb)->daddr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
						 0, IPPROTO_TCP, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
			ipcse = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		ipcss = skb_network_offset(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		tucss = skb_transport_offset(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		tucse = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
		i = tx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
		buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		context_desc->upper_setup.tcp_fields.tucss = tucss;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		context_desc->upper_setup.tcp_fields.tucso = tucso;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		buffer_info->time_stamp = jiffies;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		buffer_info->next_to_watch = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		if (++i == tx_ring->count) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
		tx_ring->next_to_use = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
	return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
static bool e1000_tx_csum(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	struct e1000_context_desc *context_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	u8 css;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 cmd_len = E1000_TXD_CMD_DEXT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	if (skb->ip_summed != CHECKSUM_PARTIAL)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		return false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	switch (skb->protocol) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	case cpu_to_be16(ETH_P_IP):
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
			cmd_len |= E1000_TXD_CMD_TCP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	case cpu_to_be16(ETH_P_IPV6):
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		/* XXX not handling all IPV6 headers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
			cmd_len |= E1000_TXD_CMD_TCP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		if (unlikely(net_ratelimit()))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
			DPRINTK(DRV, WARNING,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			        "checksum_partial proto=%x!\n", skb->protocol);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	css = skb_transport_offset(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	i = tx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	context_desc->lower_setup.ip_config = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	context_desc->upper_setup.tcp_fields.tucss = css;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	context_desc->upper_setup.tcp_fields.tucso =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		css + skb->csum_offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
	context_desc->upper_setup.tcp_fields.tucse = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	context_desc->tcp_seg_setup.data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	buffer_info->time_stamp = jiffies;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	buffer_info->next_to_watch = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	if (unlikely(++i == tx_ring->count)) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	tx_ring->next_to_use = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	return true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
#define E1000_MAX_TXD_PWR	12
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
static int e1000_tx_map(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
			struct e1000_tx_ring *tx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
			struct sk_buff *skb, unsigned int first,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
			unsigned int max_per_txd, unsigned int nr_frags,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
			unsigned int mss)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	unsigned int len = skb_headlen(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	unsigned int offset, size, count = 0, i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	unsigned int f;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	dma_addr_t *map;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	i = tx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	map = skb_shinfo(skb)->dma_maps;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	offset = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	while (len) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		size = min(len, max_per_txd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		/* Workaround for Controller erratum --
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		 * descriptor for non-tso packet in a linear SKB that follows a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		 * tso gets written back prematurely before the data is fully
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		 * DMA'd to the controller */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		if (!skb->data_len && tx_ring->last_tx_tso &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		    !skb_is_gso(skb)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
			tx_ring->last_tx_tso = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
			size -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		/* Workaround for premature desc write-backs
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		 * in TSO mode.  Append 4-byte sentinel desc */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		if (unlikely(mss && !nr_frags && size == len && size > 8))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			size -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		/* work-around for errata 10 and it applies
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		 * to all controllers in PCI-X mode
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		 * The fix is to make sure that the first descriptor of a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		                (size > 2015) && count == 0))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		        size = 2015;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		 * terminating buffers within evenly-aligned dwords. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		if (unlikely(adapter->pcix_82544 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		   size > 4))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
			size -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		buffer_info->length = size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		/* set time_stamp *before* dma to help avoid a possible race */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		buffer_info->time_stamp = jiffies;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		buffer_info->next_to_watch = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		len -= size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		offset += size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
		count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		if (len) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
			i++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
			if (unlikely(i == tx_ring->count))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
				i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	for (f = 0; f < nr_frags; f++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		struct skb_frag_struct *frag;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
		frag = &skb_shinfo(skb)->frags[f];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		len = frag->size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
		offset = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
		while (len) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
			i++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
			if (unlikely(i == tx_ring->count))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
				i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
			buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
			size = min(len, max_per_txd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
			/* Workaround for premature desc write-backs
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
			 * in TSO mode.  Append 4-byte sentinel desc */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
				size -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
			/* Workaround for potential 82544 hang in PCI-X.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			 * Avoid terminating buffers within evenly-aligned
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
			 * dwords. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
			if (unlikely(adapter->pcix_82544 &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
			    !((unsigned long)(page_to_phys(frag->page) + offset
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
			                      + size - 1) & 4) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			    size > 4))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
				size -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
			buffer_info->length = size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
			buffer_info->time_stamp = jiffies;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
			buffer_info->dma = map[f] + offset;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
			buffer_info->next_to_watch = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			len -= size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			offset += size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	tx_ring->buffer_info[i].skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	tx_ring->buffer_info[first].next_to_watch = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	return count;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
static void e1000_tx_queue(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
			   struct e1000_tx_ring *tx_ring, int tx_flags,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
			   int count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	struct e1000_tx_desc *tx_desc = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		             E1000_TXD_CMD_TSE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		txd_lower |= E1000_TXD_CMD_VLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	i = tx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	while (count--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		tx_desc = E1000_TX_DESC(*tx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
		tx_desc->lower.data =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
			cpu_to_le32(txd_lower | buffer_info->length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
		tx_desc->upper.data = cpu_to_le32(txd_upper);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
		if (unlikely(++i == tx_ring->count)) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	/* Force memory writes to complete before letting h/w
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
	 * know there are new descriptors to fetch.  (Only
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	 * applicable for weak-ordered memory model archs,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	 * such as IA-64). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	wmb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	tx_ring->next_to_use = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	writel(i, hw->hw_addr + tx_ring->tdt);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	/* we need this if more than one processor can write to our tail
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	 * at a time, it syncronizes IO on IA64/Altix systems */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	mmiowb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
 * 82547 workaround to avoid controller hang in half-duplex environment.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
 * The workaround is to avoid queuing a large packet that would span
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
 * the internal Tx FIFO ring boundary by notifying the stack to resend
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
 * to the beginning of the Tx FIFO.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
#define E1000_FIFO_HDR			0x10
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
#define E1000_82547_PAD_LEN		0x3E0
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
				       struct sk_buff *skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	if (adapter->link_duplex != HALF_DUPLEX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		goto no_fifo_stall_required;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	if (atomic_read(&adapter->tx_fifo_stall))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		return 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		atomic_set(&adapter->tx_fifo_stall, 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		return 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
no_fifo_stall_required:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	adapter->tx_fifo_head += skb_fifo_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	netif_stop_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	/* Herbert's original patch had:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	 *  smp_mb__after_netif_stop_queue();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	 * but since that doesn't exist yet, just open code it. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	smp_mb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	/* We need to check again in a case another CPU has just
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	 * made room available. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		return -EBUSY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
	/* A reprieve! */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	netif_start_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	++adapter->restart_queue;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
static int e1000_maybe_stop_tx(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
                               struct e1000_tx_ring *tx_ring, int size)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	return __e1000_maybe_stop_tx(netdev, size);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
				    struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	struct e1000_tx_ring *tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	unsigned int tx_flags = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	unsigned int len = skb->len - skb->data_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	unsigned int nr_frags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	unsigned int mss;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	int count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	int tso;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	unsigned int f;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	/* This goes back to the question of how to logically map a tx queue
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	 * to a flow.  Right now, performance is impacted slightly negatively
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	 * if using multiple tx queues.  If the stack breaks away from a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	 * single qdisc implementation, we can look at this again. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	tx_ring = adapter->tx_ring;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	if (unlikely(skb->len <= 0)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		dev_kfree_skb_any(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		return NETDEV_TX_OK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	mss = skb_shinfo(skb)->gso_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	/* The controller does a simple calculation to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	 * make sure there is enough room in the FIFO before
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	 * initiating the DMA for each buffer.  The calc is:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	 * 4 = ceil(buffer len/mss).  To make sure we don't
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	 * overrun the FIFO, adjust the max buffer len if mss
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	 * drops. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	if (mss) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		u8 hdr_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		max_per_txd = min(mss << 2, max_per_txd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
		max_txd_pwr = fls(max_per_txd) - 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		if (skb->data_len && hdr_len == len) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
			switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
				unsigned int pull_size;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
			case e1000_82544:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
				/* Make sure we have room to chop off 4 bytes,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
				 * and that the end alignment will work out to
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
				 * this hardware's requirements
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
				 * NOTE: this is a TSO only workaround
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
				 * if end byte alignment not correct move us
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
				 * into the next dword */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
					break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
				/* fall through */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
				pull_size = min((unsigned int)4, skb->data_len);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
				if (!__pskb_pull_tail(skb, pull_size)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
					DPRINTK(DRV, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
						"__pskb_pull_tail failed.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
					dev_kfree_skb_any(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
					return NETDEV_TX_OK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
				len = skb->len - skb->data_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
			default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
				/* do nothing */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	/* reserve a descriptor for the offload context */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	/* Controller Erratum workaround */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
	count += TXD_USE_COUNT(len, max_txd_pwr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	if (adapter->pcix_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	/* work-around for errata 10 and it applies to all controllers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	 * in PCI-X mode, so add one more descriptor to the count
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
			(len > 2015)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	nr_frags = skb_shinfo(skb)->nr_frags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	for (f = 0; f < nr_frags; f++)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
				       max_txd_pwr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	if (adapter->pcix_82544)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		count += nr_frags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	/* need: count + 2 desc gap to keep tail from touching
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	 * head, otherwise try next time */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		return NETDEV_TX_BUSY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	if (unlikely(hw->mac_type == e1000_82547)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			netif_stop_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
				mod_timer(&adapter->tx_fifo_stall_timer,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
				          jiffies + 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			return NETDEV_TX_BUSY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		tx_flags |= E1000_TX_FLAGS_VLAN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	first = tx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	tso = e1000_tso(adapter, tx_ring, skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	if (tso < 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		dev_kfree_skb_any(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		return NETDEV_TX_OK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	if (likely(tso)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		if (likely(hw->mac_type != e1000_82544))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			tx_ring->last_tx_tso = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		tx_flags |= E1000_TX_FLAGS_TSO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
		tx_flags |= E1000_TX_FLAGS_CSUM;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	if (likely(skb->protocol == htons(ETH_P_IP)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		tx_flags |= E1000_TX_FLAGS_IPV4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	                     nr_frags, mss);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	if (count) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		/* Make sure there is space in the ring for the next send. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		dev_kfree_skb_any(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		tx_ring->buffer_info[first].time_stamp = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		tx_ring->next_to_use = first;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	return NETDEV_TX_OK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
 * e1000_tx_timeout - Respond to a Tx Hang
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
static void e1000_tx_timeout(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	/* Do the reset outside of interrupt context */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	adapter->tx_timeout_count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	schedule_work(&adapter->reset_task);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
static void e1000_reset_task(struct work_struct *work)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	struct e1000_adapter *adapter =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		container_of(work, struct e1000_adapter, reset_task);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	e1000_reinit_locked(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
 * e1000_get_stats - Get System Network Statistics
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
 * Returns the address of the device statistics structure.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
 * The statistics are actually updated from the timer callback.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	/* only return the current stats */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	return &adapter->net_stats;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
 * e1000_change_mtu - Change the Maximum Transfer Unit
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
 * @netdev: network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
 * @new_mtu: new value for maximum frame size
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
 * Returns 0 on success, negative on failure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	/* Adapter-specific max frame size limits. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	switch (hw->mac_type) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	case e1000_undefined ... e1000_82542_rev2_1:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
			return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
		msleep(1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	/* e1000_down has a dependency on max_frame_size */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	hw->max_frame_size = max_frame;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	 * means we reserve 2 more, this pushes us to allocate from the next
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	 * larger slab size.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	 * i.e. RXBUFFER_2048 --> size-4096 slab
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	 *  fragmented skbs */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	if (max_frame <= E1000_RXBUFFER_2048)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		adapter->rx_buffer_len = PAGE_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	/* adjust allocation if LPE protects us, and we aren't using SBP */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	if (!hw->tbi_compatibility_on &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	printk(KERN_INFO "e1000: %s changing MTU from %d to %d\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	       netdev->name, netdev->mtu, new_mtu);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	netdev->mtu = new_mtu;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	clear_bit(__E1000_RESETTING, &adapter->flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
 * e1000_update_stats - Update the board statistics counters
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
void e1000_update_stats(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	unsigned long flags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	u16 phy_tmp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	 * Prevent stats update while adapter is being reset, or if the pci
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	 * connection is down.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	if (adapter->link_speed == 0)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	if (pci_channel_offline(pdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	spin_lock_irqsave(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	/* these counters are modified from e1000_tbi_adjust_stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	 * called from the interrupt context, so they must only
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	 * be written while holding adapter->stats_lock
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	adapter->stats.crcerrs += er32(CRCERRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	adapter->stats.gprc += er32(GPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	adapter->stats.gorcl += er32(GORCL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	adapter->stats.gorch += er32(GORCH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	adapter->stats.bprc += er32(BPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	adapter->stats.mprc += er32(MPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	adapter->stats.roc += er32(ROC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	adapter->stats.prc64 += er32(PRC64);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	adapter->stats.prc127 += er32(PRC127);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	adapter->stats.prc255 += er32(PRC255);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	adapter->stats.prc511 += er32(PRC511);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	adapter->stats.prc1023 += er32(PRC1023);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	adapter->stats.prc1522 += er32(PRC1522);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	adapter->stats.symerrs += er32(SYMERRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	adapter->stats.mpc += er32(MPC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	adapter->stats.scc += er32(SCC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	adapter->stats.ecol += er32(ECOL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	adapter->stats.mcc += er32(MCC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	adapter->stats.latecol += er32(LATECOL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	adapter->stats.dc += er32(DC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	adapter->stats.sec += er32(SEC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	adapter->stats.rlec += er32(RLEC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	adapter->stats.xonrxc += er32(XONRXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	adapter->stats.xontxc += er32(XONTXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	adapter->stats.xoffrxc += er32(XOFFRXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	adapter->stats.xofftxc += er32(XOFFTXC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	adapter->stats.fcruc += er32(FCRUC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	adapter->stats.gptc += er32(GPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	adapter->stats.gotcl += er32(GOTCL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	adapter->stats.gotch += er32(GOTCH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	adapter->stats.rnbc += er32(RNBC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	adapter->stats.ruc += er32(RUC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	adapter->stats.rfc += er32(RFC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	adapter->stats.rjc += er32(RJC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	adapter->stats.torl += er32(TORL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	adapter->stats.torh += er32(TORH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	adapter->stats.totl += er32(TOTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	adapter->stats.toth += er32(TOTH);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	adapter->stats.tpr += er32(TPR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	adapter->stats.ptc64 += er32(PTC64);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	adapter->stats.ptc127 += er32(PTC127);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	adapter->stats.ptc255 += er32(PTC255);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	adapter->stats.ptc511 += er32(PTC511);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	adapter->stats.ptc1023 += er32(PTC1023);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	adapter->stats.ptc1522 += er32(PTC1522);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	adapter->stats.mptc += er32(MPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	adapter->stats.bptc += er32(BPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	/* used for adaptive IFS */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	hw->tx_packet_delta = er32(TPT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	adapter->stats.tpt += hw->tx_packet_delta;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	hw->collision_delta = er32(COLC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	adapter->stats.colc += hw->collision_delta;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	if (hw->mac_type >= e1000_82543) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		adapter->stats.algnerrc += er32(ALGNERRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		adapter->stats.rxerrc += er32(RXERRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		adapter->stats.tncrs += er32(TNCRS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		adapter->stats.cexterr += er32(CEXTERR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
		adapter->stats.tsctc += er32(TSCTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
		adapter->stats.tsctfc += er32(TSCTFC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	/* Fill out the OS statistics structure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	adapter->net_stats.multicast = adapter->stats.mprc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	adapter->net_stats.collisions = adapter->stats.colc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	/* Rx Errors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	/* RLEC on some newer hardware can be incorrect so build
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	* our own version based on RUC and ROC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		adapter->stats.crcerrs + adapter->stats.algnerrc +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		adapter->stats.ruc + adapter->stats.roc +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
		adapter->stats.cexterr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	/* Tx Errors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	if (hw->bad_tx_carr_stats_fd &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	    adapter->link_duplex == FULL_DUPLEX) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		adapter->net_stats.tx_carrier_errors = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		adapter->stats.tncrs = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	/* Tx Dropped needs to be maintained elsewhere */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	/* Phy Stats */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		if ((adapter->link_speed == SPEED_1000) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
			adapter->phy_stats.idle_errors += phy_tmp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		if ((hw->mac_type <= e1000_82546) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		   (hw->phy_type == e1000_phy_m88) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
			adapter->phy_stats.receive_errors += phy_tmp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	/* Management Stats */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	if (hw->has_smbus) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		adapter->stats.mgptc += er32(MGTPTC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		adapter->stats.mgprc += er32(MGTPRC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
		adapter->stats.mgpdc += er32(MGTPDC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
 * e1000_intr - Interrupt Handler
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
 * @irq: interrupt number
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
 * @data: pointer to a network interface device structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
static irqreturn_t e1000_intr(int irq, void *data)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	struct net_device *netdev = data;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	u32 icr = er32(ICR);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		return IRQ_NONE;  /* Not our interrupt */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		hw->get_link_status = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		/* guard against interrupt when we're going down */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	/* disable interrupts, without the synchronize_irq bit */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	ew32(IMC, ~0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	E1000_WRITE_FLUSH();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	if (likely(napi_schedule_prep(&adapter->napi))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		adapter->total_tx_bytes = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
		adapter->total_tx_packets = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		adapter->total_rx_bytes = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
		adapter->total_rx_packets = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
		__napi_schedule(&adapter->napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
		/* this really should not happen! if it does it is basically a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
		 * bug, but not a hard error, so enable ints and continue */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
			e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	return IRQ_HANDLED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
 * e1000_clean - NAPI Rx polling callback
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
static int e1000_clean(struct napi_struct *napi, int budget)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	int tx_clean_complete = 0, work_done = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	if (!tx_clean_complete)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
		work_done = budget;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	/* If budget not fully consumed, exit the polling mode */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	if (work_done < budget) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		if (likely(adapter->itr_setting & 3))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
			e1000_set_itr(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		napi_complete(napi);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
			e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	return work_done;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
			       struct e1000_tx_ring *tx_ring)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	struct e1000_tx_desc *tx_desc, *eop_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	unsigned int i, eop;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	unsigned int count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	unsigned int total_tx_bytes=0, total_tx_packets=0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	i = tx_ring->next_to_clean;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
	eop = tx_ring->buffer_info[i].next_to_watch;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	       (count < tx_ring->count)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		bool cleaned = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		for ( ; !cleaned; count++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
			tx_desc = E1000_TX_DESC(*tx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
			buffer_info = &tx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
			cleaned = (i == eop);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
			if (cleaned) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
				struct sk_buff *skb = buffer_info->skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
				unsigned int segs, bytecount;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
				segs = skb_shinfo(skb)->gso_segs ?: 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
				/* multiply data chunks by size of headers */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
				bytecount = ((segs - 1) * skb_headlen(skb)) +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
				            skb->len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
				total_tx_packets += segs;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
				total_tx_bytes += bytecount;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
			tx_desc->upper.data = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
			if (unlikely(++i == tx_ring->count)) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
		eop = tx_ring->buffer_info[i].next_to_watch;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	tx_ring->next_to_clean = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
#define TX_WAKE_THRESHOLD 32
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	if (unlikely(count && netif_carrier_ok(netdev) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		/* Make sure that anybody stopping the queue after this
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		 * sees the new next_to_clean.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		smp_mb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
		if (netif_queue_stopped(netdev) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
			netif_wake_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
			++adapter->restart_queue;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	if (adapter->detect_tx_hung) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		/* Detect a transmit hang in hardware, this serializes the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		 * check with the clearing of time_stamp and movement of i */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		adapter->detect_tx_hung = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		if (tx_ring->buffer_info[eop].time_stamp &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		               (adapter->tx_timeout_factor * HZ))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			/* detected Tx unit hang */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
					"  Tx Queue             <%lu>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
					"  TDH                  <%x>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
					"  TDT                  <%x>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
					"  next_to_use          <%x>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
					"  next_to_clean        <%x>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
					"buffer_info[next_to_clean]\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
					"  time_stamp           <%lx>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
					"  next_to_watch        <%x>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
					"  jiffies              <%lx>\n"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
					"  next_to_watch.status <%x>\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
				(unsigned long)((tx_ring - adapter->tx_ring) /
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
					sizeof(struct e1000_tx_ring)),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
				readl(hw->hw_addr + tx_ring->tdh),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
				readl(hw->hw_addr + tx_ring->tdt),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
				tx_ring->next_to_use,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
				tx_ring->next_to_clean,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
				tx_ring->buffer_info[eop].time_stamp,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
				eop,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
				jiffies,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
				eop_desc->upper.fields.status);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
			netif_stop_queue(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	adapter->total_tx_bytes += total_tx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	adapter->total_tx_packets += total_tx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	adapter->net_stats.tx_bytes += total_tx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	adapter->net_stats.tx_packets += total_tx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	return (count < tx_ring->count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
 * e1000_rx_checksum - Receive Checksum Offload for 82543
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
 * @adapter:     board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
 * @status_err:  receive descriptor status and error fields
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
 * @csum:        receive descriptor csum field
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
 * @sk_buff:     socket buffer with received data
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
			      u32 csum, struct sk_buff *skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	u16 status = (u16)status_err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	u8 errors = (u8)(status_err >> 24);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	skb->ip_summed = CHECKSUM_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	/* 82543 or newer only */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	if (unlikely(hw->mac_type < e1000_82543)) return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	/* Ignore Checksum bit is set */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	/* TCP/UDP checksum error bit is set */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		/* let the stack verify checksum errors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		adapter->hw_csum_err++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	/* TCP/UDP Checksum has not been calculated */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	if (!(status & E1000_RXD_STAT_TCPCS))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	/* It must be a TCP or UDP packet with a valid checksum */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		/* TCP checksum is good */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		skb->ip_summed = CHECKSUM_UNNECESSARY;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	adapter->hw_csum_good++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
 * e1000_consume_page - helper function
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
                               u16 length)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
	bi->page = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	skb->len += length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
	skb->data_len += length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	skb->truesize += length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
 * e1000_receive_skb - helper function to handle rx indications
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
 * @status: descriptor status field as written by hardware
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
 * @skb: pointer to sk_buff to be indicated to stack
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
			      __le16 vlan, struct sk_buff *skb)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		                         le16_to_cpu(vlan) &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		                         E1000_RXD_SPC_VLAN_MASK);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		netif_receive_skb(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
 * @rx_ring: ring to clean
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
 * @work_done: amount of napi work completed this call
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
 * @work_to_do: max amount of work allowed for this call to do
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
 * the return value indicates whether actual cleaning was done, there
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
 * is no guarantee that everything was cleaned
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
				     struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
				     int *work_done, int work_to_do)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	struct e1000_rx_desc *rx_desc, *next_rxd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	struct e1000_buffer *buffer_info, *next_buffer;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	unsigned long irq_flags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	u32 length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	int cleaned_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	bool cleaned = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	unsigned int total_rx_bytes=0, total_rx_packets=0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	i = rx_ring->next_to_clean;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	rx_desc = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	while (rx_desc->status & E1000_RXD_STAT_DD) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		u8 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		if (*work_done >= work_to_do)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		(*work_done)++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		status = rx_desc->status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		skb = buffer_info->skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		buffer_info->skb = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		if (++i == rx_ring->count) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		next_rxd = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		prefetch(next_rxd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
		next_buffer = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		cleaned = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		cleaned_count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		               PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		buffer_info->dma = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		length = le16_to_cpu(rx_desc->length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		/* errors is only valid for DD + EOP descriptors */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
			u8 last_byte = *(skb->data + length - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
				       last_byte)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
				spin_lock_irqsave(&adapter->stats_lock,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
				                  irq_flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
				e1000_tbi_adjust_stats(hw, &adapter->stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
				                       length, skb->data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
				spin_unlock_irqrestore(&adapter->stats_lock,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
				                       irq_flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
				length--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
				/* recycle both page and skb */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
				buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
				/* an error means any chain goes out the window
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
				 * too */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
				if (rx_ring->rx_skb_top)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
					dev_kfree_skb(rx_ring->rx_skb_top);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
				rx_ring->rx_skb_top = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
				goto next_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
#define rxtop rx_ring->rx_skb_top
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		if (!(status & E1000_RXD_STAT_EOP)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
			/* this descriptor is only the beginning (or middle) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
			if (!rxtop) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
				/* this is the beginning of a chain */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
				rxtop = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
				                   0, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
				/* this is the middle of a chain */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
				skb_fill_page_desc(rxtop,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
				    skb_shinfo(rxtop)->nr_frags,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
				    buffer_info->page, 0, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
				/* re-use the skb, only consumed the page */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
				buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
			e1000_consume_page(buffer_info, rxtop, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
			goto next_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
			if (rxtop) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
				/* end of the chain */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
				skb_fill_page_desc(rxtop,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
				    skb_shinfo(rxtop)->nr_frags,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
				    buffer_info->page, 0, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
				/* re-use the current skb, we only consumed the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
				 * page */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
				buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
				skb = rxtop;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
				rxtop = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
				e1000_consume_page(buffer_info, skb, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
				/* no chain, got EOP, this buf is the packet
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
				 * copybreak to save the put_page/alloc_page */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
				if (length <= copybreak &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
				    skb_tailroom(skb) >= length) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
					u8 *vaddr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
					vaddr = kmap_atomic(buffer_info->page,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
					                    KM_SKB_DATA_SOFTIRQ);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
					memcpy(skb_tail_pointer(skb), vaddr, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
					kunmap_atomic(vaddr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
					              KM_SKB_DATA_SOFTIRQ);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
					/* re-use the page, so don't erase
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
					 * buffer_info->page */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
					skb_put(skb, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
				} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
					skb_fill_page_desc(skb, 0,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
					                   buffer_info->page, 0,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
				                           length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
					e1000_consume_page(buffer_info, skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
					                   length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		e1000_rx_checksum(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
		                  (u32)(status) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
		                  ((u32)(rx_desc->errors) << 24),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
		                  le16_to_cpu(rx_desc->csum), skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
		pskb_trim(skb, skb->len - 4);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
		/* probably a little skewed due to removing CRC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		total_rx_bytes += skb->len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
		total_rx_packets++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
		/* eth type trans needs skb->data to point to something */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
		if (!pskb_may_pull(skb, ETH_HLEN)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
			DPRINTK(DRV, ERR, "pskb_may_pull failed.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
			dev_kfree_skb(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
			goto next_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		skb->protocol = eth_type_trans(skb, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
next_desc:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		rx_desc->status = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		/* return some buffers to hardware, one at a time is too slow */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
			cleaned_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		/* use prefetched values */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		rx_desc = next_rxd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		buffer_info = next_buffer;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	rx_ring->next_to_clean = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	if (cleaned_count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	adapter->total_rx_packets += total_rx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	adapter->total_rx_bytes += total_rx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	adapter->net_stats.rx_bytes += total_rx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	adapter->net_stats.rx_packets += total_rx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	return cleaned;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
 * @adapter: board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
 * @rx_ring: ring to clean
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
 * @work_done: amount of napi work completed this call
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
 * @work_to_do: max amount of work allowed for this call to do
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
			       struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
			       int *work_done, int work_to_do)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	struct e1000_rx_desc *rx_desc, *next_rxd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	struct e1000_buffer *buffer_info, *next_buffer;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	unsigned long flags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	u32 length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	int cleaned_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	bool cleaned = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	unsigned int total_rx_bytes=0, total_rx_packets=0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	i = rx_ring->next_to_clean;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	rx_desc = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	while (rx_desc->status & E1000_RXD_STAT_DD) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		u8 status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		if (*work_done >= work_to_do)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		(*work_done)++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		status = rx_desc->status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		skb = buffer_info->skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
		buffer_info->skb = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		prefetch(skb->data - NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		if (++i == rx_ring->count) i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		next_rxd = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		prefetch(next_rxd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		next_buffer = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		cleaned = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		cleaned_count++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		pci_unmap_single(pdev, buffer_info->dma, buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		                 PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		buffer_info->dma = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		length = le16_to_cpu(rx_desc->length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		/* !EOP means multiple descriptors were used to store a single
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		 * packet, if thats the case we need to toss it.  In fact, we
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		 * to toss every packet with the EOP bit clear and the next
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		 * frame that _does_ have the EOP bit set, as it is by
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		 * definition only a frame fragment
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
			adapter->discarding = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		if (adapter->discarding) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
			/* All receives must fit into a single buffer */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
			E1000_DBG("%s: Receive packet consumed multiple"
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
				  " buffers\n", netdev->name);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
			/* recycle */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
			buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
			if (status & E1000_RXD_STAT_EOP)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
				adapter->discarding = false;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
			goto next_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
			u8 last_byte = *(skb->data + length - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
				       last_byte)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
				spin_lock_irqsave(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
				e1000_tbi_adjust_stats(hw, &adapter->stats,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
				                       length, skb->data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
				spin_unlock_irqrestore(&adapter->stats_lock,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
				                       flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
				length--;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
			} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
				/* recycle */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
				buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
				goto next_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		/* adjust length to remove Ethernet CRC, this must be
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		 * done after the TBI_ACCEPT workaround above */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		length -= 4;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		/* probably a little skewed due to removing CRC */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		total_rx_bytes += length;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		total_rx_packets++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		/* code added for copybreak, this should improve
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		 * performance for small packets with large amounts
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		 * of reassembly being done in the stack */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		if (length < copybreak) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
			struct sk_buff *new_skb =
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
			if (new_skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
				skb_reserve(new_skb, NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
				skb_copy_to_linear_data_offset(new_skb,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
							       -NET_IP_ALIGN,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
							       (skb->data -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
							        NET_IP_ALIGN),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
							       (length +
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
							        NET_IP_ALIGN));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
				/* save the skb in buffer_info as good */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
				buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
				skb = new_skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
			/* else just continue with the old one */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		/* end copybreak code */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		skb_put(skb, length);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
		/* Receive Checksum Offload */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		e1000_rx_checksum(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
				  (u32)(status) |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
				  ((u32)(rx_desc->errors) << 24),
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
				  le16_to_cpu(rx_desc->csum), skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
		skb->protocol = eth_type_trans(skb, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
next_desc:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		rx_desc->status = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		/* return some buffers to hardware, one at a time is too slow */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
			cleaned_count = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
		/* use prefetched values */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
		rx_desc = next_rxd;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
		buffer_info = next_buffer;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	rx_ring->next_to_clean = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	if (cleaned_count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	adapter->total_rx_packets += total_rx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	adapter->total_rx_bytes += total_rx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	adapter->net_stats.rx_bytes += total_rx_bytes;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
	adapter->net_stats.rx_packets += total_rx_packets;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	return cleaned;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
 * @adapter: address of board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
 * @rx_ring: pointer to receive ring structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
 * @cleaned_count: number of buffers to allocate this pass
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
static void
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	struct e1000_rx_desc *rx_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
	struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
	unsigned int bufsz = 256 -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	                     16 /*for skb_reserve */ -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	                     NET_IP_ALIGN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	i = rx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	while (cleaned_count--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		skb = buffer_info->skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
		if (skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
			skb_trim(skb, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
			goto check_page;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
		skb = netdev_alloc_skb(netdev, bufsz);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		if (unlikely(!skb)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
			/* Better luck next round */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
			adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
		/* Fix for errata 23, can't cross 64kB boundary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
			struct sk_buff *oldskb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
			DPRINTK(PROBE, ERR, "skb align check failed: %u bytes "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
					     "at %p\n", bufsz, skb->data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			/* Try again, without freeing the previous */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			skb = netdev_alloc_skb(netdev, bufsz);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			/* Failed allocation, critical failure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
			if (!skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
				dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
				adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
				/* give up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
				dev_kfree_skb(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
				dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
				break; /* while (cleaned_count--) */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
			/* Use new allocation */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
			dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		/* Make buffer alignment 2 beyond a 16 byte boundary
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		 * this will result in a 16 byte aligned IP header after
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		 * the 14 byte MAC header is removed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		skb_reserve(skb, NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
		buffer_info->length = adapter->rx_buffer_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
check_page:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
		/* allocate a new page if necessary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		if (!buffer_info->page) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
			buffer_info->page = alloc_page(GFP_ATOMIC);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
			if (unlikely(!buffer_info->page)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
				adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		if (!buffer_info->dma)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			buffer_info->dma = pci_map_page(pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
			                                buffer_info->page, 0,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
			                                buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
			                                PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		rx_desc = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
		if (unlikely(++i == rx_ring->count))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
			i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	if (likely(rx_ring->next_to_use != i)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
		rx_ring->next_to_use = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		if (unlikely(i-- == 0))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
			i = (rx_ring->count - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		/* Force memory writes to complete before letting h/w
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
		 * know there are new descriptors to fetch.  (Only
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		 * applicable for weak-ordered memory model archs,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		 * such as IA-64). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
		wmb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
 * @adapter: address of board private structure
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
				   struct e1000_rx_ring *rx_ring,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
				   int cleaned_count)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
	struct net_device *netdev = adapter->netdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
	struct pci_dev *pdev = adapter->pdev;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	struct e1000_rx_desc *rx_desc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	struct e1000_buffer *buffer_info;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	struct sk_buff *skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	unsigned int i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	i = rx_ring->next_to_use;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	while (cleaned_count--) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
		skb = buffer_info->skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		if (skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
			skb_trim(skb, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
			goto map_skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		skb = netdev_alloc_skb(netdev, bufsz);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
		if (unlikely(!skb)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			/* Better luck next round */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
			break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		/* Fix for errata 23, can't cross 64kB boundary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			struct sk_buff *oldskb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
					     "at %p\n", bufsz, skb->data);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
			/* Try again, without freeing the previous */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
			skb = netdev_alloc_skb(netdev, bufsz);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			/* Failed allocation, critical failure */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
			if (!skb) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
				dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
				adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
				/* give up */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
				dev_kfree_skb(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
				dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
				adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
				break; /* while !buffer_info->skb */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
			/* Use new allocation */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
			dev_kfree_skb(oldskb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
		/* Make buffer alignment 2 beyond a 16 byte boundary
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
		 * this will result in a 16 byte aligned IP header after
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
		 * the 14 byte MAC header is removed
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
		skb_reserve(skb, NET_IP_ALIGN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		buffer_info->skb = skb;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
		buffer_info->length = adapter->rx_buffer_len;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
map_skb:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		buffer_info->dma = pci_map_single(pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
						  skb->data,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
						  buffer_info->length,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
						  PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		 * XXX if it was allocated cleanly it will never map to a
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		 * boundary crossing
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
		 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		/* Fix for errata 23, can't cross 64kB boundary */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		if (!e1000_check_64k_bound(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
					(void *)(unsigned long)buffer_info->dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
					adapter->rx_buffer_len)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
			DPRINTK(RX_ERR, ERR,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				"dma align check failed: %u bytes at %p\n",
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
				adapter->rx_buffer_len,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
				(void *)(unsigned long)buffer_info->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
			dev_kfree_skb(skb);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
			buffer_info->skb = NULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			pci_unmap_single(pdev, buffer_info->dma,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
					 adapter->rx_buffer_len,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
					 PCI_DMA_FROMDEVICE);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
			buffer_info->dma = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
			adapter->alloc_rx_buff_failed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
			break; /* while !buffer_info->skb */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
		rx_desc = E1000_RX_DESC(*rx_ring, i);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		if (unlikely(++i == rx_ring->count))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
			i = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		buffer_info = &rx_ring->buffer_info[i];
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	if (likely(rx_ring->next_to_use != i)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		rx_ring->next_to_use = i;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		if (unlikely(i-- == 0))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			i = (rx_ring->count - 1);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		/* Force memory writes to complete before letting h/w
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
		 * know there are new descriptors to fetch.  (Only
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		 * applicable for weak-ordered memory model archs,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		 * such as IA-64). */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		wmb();
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		writel(i, hw->hw_addr + rx_ring->rdt);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
 * @adapter:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
static void e1000_smartspeed(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	u16 phy_status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
	u16 phy_ctrl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
	if (adapter->smartspeed == 0) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
		/* If Master/Slave config fault is asserted twice,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		 * we assume back-to-back */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
					    phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
			adapter->smartspeed++;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
			if (!e1000_phy_setup_autoneg(hw) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			   !e1000_read_phy_reg(hw, PHY_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
				   	       &phy_ctrl)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
					     MII_CR_RESTART_AUTO_NEG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
				e1000_write_phy_reg(hw, PHY_CTRL,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
						    phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		/* If still no link, perhaps using 2/3 pair cable */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
		phy_ctrl |= CR_1000T_MS_ENABLE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
		if (!e1000_phy_setup_autoneg(hw) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
				     MII_CR_RESTART_AUTO_NEG);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		adapter->smartspeed = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
 * e1000_ioctl -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
 * @netdev:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
 * @ifreq:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
 * @cmd:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	switch (cmd) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	case SIOCGMIIPHY:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	case SIOCGMIIREG:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	case SIOCSMIIREG:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		return e1000_mii_ioctl(netdev, ifr, cmd);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
 * e1000_mii_ioctl -
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
 * @netdev:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
 * @ifreq:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
 * @cmd:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
 **/
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
			   int cmd)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	struct mii_ioctl_data *data = if_mii(ifr);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	int retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	u16 mii_reg;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	u16 spddplx;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	unsigned long flags;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	if (hw->media_type != e1000_media_type_copper)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	switch (cmd) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	case SIOCGMIIPHY:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
		data->phy_id = hw->phy_addr;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	case SIOCGMIIREG:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
		spin_lock_irqsave(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
				   &data->val_out)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			return -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	case SIOCSMIIREG:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
		if (data->reg_num & ~(0x1F))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
			return -EFAULT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		mii_reg = data->val_in;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
		spin_lock_irqsave(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		if (e1000_write_phy_reg(hw, data->reg_num,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
					mii_reg)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
			return -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		if (hw->media_type == e1000_media_type_copper) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
			switch (data->reg_num) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
			case PHY_CTRL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
				if (mii_reg & MII_CR_POWER_DOWN)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
					break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
					hw->autoneg = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
					hw->autoneg_advertised = 0x2F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
				} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
					if (mii_reg & 0x40)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
						spddplx = SPEED_1000;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
					else if (mii_reg & 0x2000)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
						spddplx = SPEED_100;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
					else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
						spddplx = SPEED_10;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
					spddplx += (mii_reg & 0x100)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
						   ? DUPLEX_FULL :
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
						   DUPLEX_HALF;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
					retval = e1000_set_spd_dplx(adapter,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
								    spddplx);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
					if (retval)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
						return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
				}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
				if (netif_running(adapter->netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
					e1000_reinit_locked(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
				else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
					e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
			case M88E1000_PHY_SPEC_CTRL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
			case M88E1000_EXT_PHY_SPEC_CTRL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
				if (e1000_phy_reset(hw))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
					return -EIO;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
			switch (data->reg_num) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
			case PHY_CTRL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
				if (mii_reg & MII_CR_POWER_DOWN)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
					break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
				if (netif_running(adapter->netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
					e1000_reinit_locked(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
				else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
					e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
				break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
			}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
		return -EOPNOTSUPP;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	return E1000_SUCCESS;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
void e1000_pci_set_mwi(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	struct e1000_adapter *adapter = hw->back;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	int ret_val = pci_set_mwi(adapter->pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
	if (ret_val)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
void e1000_pci_clear_mwi(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
	struct e1000_adapter *adapter = hw->back;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	pci_clear_mwi(adapter->pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	struct e1000_adapter *adapter = hw->back;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	return pcix_get_mmrbc(adapter->pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	struct e1000_adapter *adapter = hw->back;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	pcix_set_mmrbc(adapter->pdev, mmrbc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	outl(value, port);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
static void e1000_vlan_rx_register(struct net_device *netdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
				   struct vlan_group *grp)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	u32 ctrl, rctl;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
		e1000_irq_disable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	adapter->vlgrp = grp;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	if (grp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		/* enable VLAN tag insert/strip */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
		ctrl |= E1000_CTRL_VME;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		/* enable VLAN receive filtering */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
		rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
		rctl &= ~E1000_RCTL_CFIEN;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		if (!(netdev->flags & IFF_PROMISC))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
			rctl |= E1000_RCTL_VFE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		e1000_update_mng_vlan(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		/* disable VLAN tag insert/strip */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
		ctrl &= ~E1000_CTRL_VME;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
		ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		/* disable VLAN receive filtering */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		rctl &= ~E1000_RCTL_VFE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
		ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
		e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	u32 vfta, index;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	if ((hw->mng_cookie.status &
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	    (vid == adapter->mng_vlan_id))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	/* add VID to filter table */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	index = (vid >> 5) & 0x7F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	vfta |= (1 << (vid & 0x1F));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	e1000_write_vfta(hw, index, vfta);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	u32 vfta, index;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		e1000_irq_disable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		e1000_irq_enable(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	/* remove VID from filter table */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	index = (vid >> 5) & 0x7F;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	vfta &= ~(1 << (vid & 0x1F));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	e1000_write_vfta(hw, index, vfta);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
static void e1000_restore_vlan(struct e1000_adapter *adapter)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	if (adapter->vlgrp) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		u16 vid;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
			if (!vlan_group_get_device(adapter->vlgrp, vid))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
				continue;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	hw->autoneg = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	/* Fiber NICs only allow 1000 gbps Full duplex */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
	if ((hw->media_type == e1000_media_type_fiber) &&
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	switch (spddplx) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	case SPEED_10 + DUPLEX_HALF:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
		hw->forced_speed_duplex = e1000_10_half;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
	case SPEED_10 + DUPLEX_FULL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		hw->forced_speed_duplex = e1000_10_full;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	case SPEED_100 + DUPLEX_HALF:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
		hw->forced_speed_duplex = e1000_100_half;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	case SPEED_100 + DUPLEX_FULL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
		hw->forced_speed_duplex = e1000_100_full;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
	case SPEED_1000 + DUPLEX_FULL:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
		hw->autoneg = 1;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		break;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	default:
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		return -EINVAL;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	u32 ctrl, ctrl_ext, rctl, status;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	u32 wufc = adapter->wol;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
#ifdef CONFIG_PM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	int retval = 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
	netif_device_detach(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	if (netif_running(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
#ifdef CONFIG_PM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	retval = pci_save_state(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	if (retval)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	status = er32(STATUS);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	if (status & E1000_STATUS_LU)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		wufc &= ~E1000_WUFC_LNKC;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	if (wufc) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		e1000_setup_rctl(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		e1000_set_rx_mode(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		/* turn on all-multi mode if wake on multicast is enabled */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		if (wufc & E1000_WUFC_MC) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
			rctl = er32(RCTL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			rctl |= E1000_RCTL_MPE;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
			ew32(RCTL, rctl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		if (hw->mac_type >= e1000_82540) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
			ctrl = er32(CTRL);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
			/* advertise wake from D3Cold */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
			#define E1000_CTRL_ADVD3WUC 0x00100000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
			/* phy power management enable */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			ctrl |= E1000_CTRL_ADVD3WUC |
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
				E1000_CTRL_EN_PHY_PWR_MGMT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			ew32(CTRL, ctrl);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		if (hw->media_type == e1000_media_type_fiber ||
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		    hw->media_type == e1000_media_type_internal_serdes) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
			/* keep the laser running in D3 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
			ctrl_ext = er32(CTRL_EXT);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
			ew32(CTRL_EXT, ctrl_ext);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		ew32(WUC, E1000_WUC_PME_EN);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
		ew32(WUFC, wufc);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		ew32(WUC, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		ew32(WUFC, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	e1000_release_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	*enable_wake = !!wufc;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	/* make sure adapter isn't asleep if manageability is enabled */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	if (adapter->en_mng_pt)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		*enable_wake = true;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		e1000_free_irq(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	pci_disable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
#ifdef CONFIG_PM
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	int retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	bool wake;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	retval = __e1000_shutdown(pdev, &wake);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	if (retval)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		return retval;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	if (wake) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
		pci_prepare_to_sleep(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	} else {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		pci_wake_from_d3(pdev, false);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		pci_set_power_state(pdev, PCI_D3hot);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
static int e1000_resume(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	u32 err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	pci_set_power_state(pdev, PCI_D0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	pci_restore_state(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	if (adapter->need_ioport)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		err = pci_enable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		err = pci_enable_device_mem(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	pci_set_master(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	pci_enable_wake(pdev, PCI_D3hot, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	pci_enable_wake(pdev, PCI_D3cold, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	if (netif_running(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
		err = e1000_request_irq(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		if (err)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
			return err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	e1000_power_up_phy(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	ew32(WUS, ~0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	e1000_init_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
		e1000_up(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	netif_device_attach(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	return 0;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
static void e1000_shutdown(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	bool wake;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	__e1000_shutdown(pdev, &wake);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
	if (system_state == SYSTEM_POWER_OFF) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		pci_wake_from_d3(pdev, wake);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		pci_set_power_state(pdev, PCI_D3hot);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
#ifdef CONFIG_NET_POLL_CONTROLLER
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
/*
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
 * Polling 'interrupt' - used by things like netconsole to send skbs
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
 * without having to re-enable interrupts. It's not called while
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
 * the interrupt routine is executing.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
static void e1000_netpoll(struct net_device *netdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	disable_irq(adapter->pdev->irq);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
	e1000_intr(adapter->pdev->irq, netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	enable_irq(adapter->pdev->irq);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
#endif
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
 * e1000_io_error_detected - called when PCI error is detected
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
 * @pdev: Pointer to PCI device
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
 * @state: The current pci connection state
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
 * This function is called after a PCI bus error affecting
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
 * this device has been detected.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
						pci_channel_state_t state)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	netif_device_detach(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
	if (state == pci_channel_io_perm_failure)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		return PCI_ERS_RESULT_DISCONNECT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	if (netif_running(netdev))
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		e1000_down(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	pci_disable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	/* Request a slot slot reset. */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	return PCI_ERS_RESULT_NEED_RESET;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
 * e1000_io_slot_reset - called after the pci bus has been reset.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
 * @pdev: Pointer to PCI device
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
 * Restart the card from scratch, as if from a cold-boot. Implementation
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
 * resembles the first-half of the e1000_resume routine.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	struct e1000_hw *hw = &adapter->hw;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	int err;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	if (adapter->need_ioport)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
		err = pci_enable_device(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	else
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		err = pci_enable_device_mem(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	if (err) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
		return PCI_ERS_RESULT_DISCONNECT;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	pci_set_master(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
	pci_enable_wake(pdev, PCI_D3hot, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	pci_enable_wake(pdev, PCI_D3cold, 0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	e1000_reset(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	ew32(WUS, ~0);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	return PCI_ERS_RESULT_RECOVERED;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
/**
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
 * e1000_io_resume - called when traffic can start flowing again.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
 * @pdev: Pointer to PCI device
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
 *
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
 * This callback is called when the error recovery driver tells us that
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
 * its OK to resume normal operation. Implementation resembles the
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
 * second-half of the e1000_resume routine.
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
 */
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
static void e1000_io_resume(struct pci_dev *pdev)
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
{
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	struct net_device *netdev = pci_get_drvdata(pdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	struct e1000_adapter *adapter = netdev_priv(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	e1000_init_manageability(adapter);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	if (netif_running(netdev)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		if (e1000_up(adapter)) {
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
			printk("e1000: can't bring device back up after reset\n");
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
			return;
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
		}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	netif_device_attach(netdev);
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
}
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
4eff8c9cfbbc Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
/* e1000_main.c */