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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
  vim: noexpandtab
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000-3.0-ethercat.h"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <net/ip6_checksum.h>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/io.h>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/prefetch.h>
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
/* Intel Media SOC GbE MDIO physical base address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
static unsigned long ce4100_gbe_mdio_base_phy;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* Intel Media SOC GbE MDIO virtual base address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
void __iomem *ce4100_gbe_mdio_base_virt;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
char e1000_driver_name[] = "ec_e1000";
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#define DRV_VERSION "7.3.21-k8-NAPI"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
const char e1000_driver_version[] = DRV_VERSION;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
/* e1000_pci_tbl - PCI Device ID Table
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 * Last entry must be all 0s
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
 * Macro expands to...
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	INTEL_E1000_ETHERNET_DEVICE(0x2E6E),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	/* required last entry */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	{0,}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
// do not auto-load driver
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
int e1000_up(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
void e1000_down(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
void e1000_reinit_locked(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
void e1000_reset(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
                             struct e1000_tx_ring *txdr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
                             struct e1000_rx_ring *rxdr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
                             struct e1000_tx_ring *tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
                             struct e1000_rx_ring *rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
void e1000_update_stats(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static int e1000_init_module(void);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_exit_module(void);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void __devexit e1000_remove(struct pci_dev *pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
static int e1000_alloc_queues(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static int e1000_sw_init(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static int e1000_open(struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static int e1000_close(struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_configure_tx(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_configure_rx(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_setup_rctl(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
                                struct e1000_tx_ring *tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
                                struct e1000_rx_ring *rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static void e1000_set_rx_mode(struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static void e1000_update_phy_info(unsigned long data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static void e1000_update_phy_info_task(struct work_struct *work);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static void e1000_watchdog(unsigned long data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static void e1000_82547_tx_fifo_stall(unsigned long data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
				    struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_set_mac(struct net_device *netdev, void *p);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
void ec_poll(struct net_device *);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static irqreturn_t e1000_intr(int irq, void *data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
			       struct e1000_tx_ring *tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static int e1000_clean(struct napi_struct *napi, int budget);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			       struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
			       int *work_done, int work_to_do);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
				     struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
				     int *work_done, int work_to_do);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
				   struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
				   int cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
					 struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
					 int cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
			   int cmd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static void e1000_tx_timeout(struct net_device *dev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static void e1000_reset_task(struct work_struct *work);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_smartspeed(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
                                       struct sk_buff *skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
static void e1000_restore_vlan(struct e1000_adapter *adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
#ifdef CONFIG_PM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
static int e1000_resume(struct pci_dev *pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static void e1000_shutdown(struct pci_dev *pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
#ifdef CONFIG_NET_POLL_CONTROLLER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
/* for netdump / net console */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
static void e1000_netpoll (struct net_device *netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
#define COPYBREAK_DEFAULT 256
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
module_param(copybreak, uint, 0644);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
MODULE_PARM_DESC(copybreak,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	"Maximum size of packet that is copied to a new buffer on receive");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
                     pci_channel_state_t state);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
static void e1000_io_resume(struct pci_dev *pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
static struct pci_error_handlers e1000_err_handler = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.error_detected = e1000_io_error_detected,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	.slot_reset = e1000_io_slot_reset,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.resume = e1000_io_resume,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
static struct pci_driver e1000_driver = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	.name     = e1000_driver_name,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	.id_table = e1000_pci_tbl,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	.probe    = e1000_probe,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	.remove   = __devexit_p(e1000_remove),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
#ifdef CONFIG_PM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	/* Power Management Hooks */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	.suspend  = e1000_suspend,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	.resume   = e1000_resume,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	.shutdown = e1000_shutdown,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	.err_handler = &e1000_err_handler
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
MODULE_LICENSE("GPL");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
MODULE_VERSION(DRV_VERSION);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
module_param(debug, int, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
 * e1000_get_hw_dev - return device
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
 * used by hardware layer to print debugging information
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	struct e1000_adapter *adapter = hw->back;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	return adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 * e1000_init_module - Driver Registration Routine
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 * e1000_init_module is the first routine called when the driver is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 * loaded. All it does is register with the PCI subsystem.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
static int __init e1000_init_module(void)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	int ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	pr_info("%s\n", e1000_copyright);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	ret = pci_register_driver(&e1000_driver);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	if (copybreak != COPYBREAK_DEFAULT) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		if (copybreak == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			pr_info("copybreak disabled\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
			pr_info("copybreak enabled for "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
				   "packets <= %u bytes\n", copybreak);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	return ret;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
module_init(e1000_init_module);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
 * e1000_exit_module - Driver Exit Cleanup Routine
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
 * e1000_exit_module is called just before the driver is removed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
 * from memory.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
static void __exit e1000_exit_module(void)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	pci_unregister_driver(&e1000_driver);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
module_exit(e1000_exit_module);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
static int e1000_request_irq(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	irq_handler_t handler = e1000_intr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	int irq_flags = IRQF_SHARED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	int err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	                  netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
static void e1000_free_irq(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	free_irq(adapter->pdev->irq, netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
 * e1000_irq_disable - Mask off interrupt generation on the NIC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
static void e1000_irq_disable(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	ew32(IMC, ~0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	synchronize_irq(adapter->pdev->irq);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 * e1000_irq_enable - Enable default interrupt generation settings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
static void e1000_irq_enable(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	ew32(IMS, IMS_ENABLE_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	u16 vid = hw->mng_cookie.vlan_id;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	u16 old_vid = adapter->mng_vlan_id;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	if (adapter->vlgrp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
			if (hw->mng_cookie.status &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
				e1000_vlan_rx_add_vid(netdev, vid);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
				adapter->mng_vlan_id = vid;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
			} else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
					(vid != old_vid) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
				e1000_vlan_rx_kill_vid(netdev, old_vid);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		} else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
			adapter->mng_vlan_id = vid;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
static void e1000_init_manageability(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	if (adapter->en_mng_pt) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		u32 manc = er32(MANC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		/* disable hardware interception of ARP */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		manc &= ~(E1000_MANC_ARP_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		ew32(MANC, manc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
static void e1000_release_manageability(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	if (adapter->en_mng_pt) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		u32 manc = er32(MANC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		/* re-enable hardware interception of ARP */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		manc |= E1000_MANC_ARP_EN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		ew32(MANC, manc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
 * e1000_configure - configure the hardware for RX and TX
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
 * @adapter = private board structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
static void e1000_configure(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	e1000_set_rx_mode(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	e1000_restore_vlan(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	e1000_init_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	e1000_configure_tx(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	e1000_setup_rctl(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	e1000_configure_rx(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	/* call E1000_DESC_UNUSED which always leaves
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	 * at least 1 descriptor unused to make sure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	 * next_to_use != next_to_clean */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	for (i = 0; i < adapter->num_rx_queues; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
			/* fill rx ring completely! */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
			adapter->alloc_rx_buf(adapter, ring, ring->count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			/* this one leaves the last ring element unallocated! */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			adapter->alloc_rx_buf(adapter, ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
					E1000_DESC_UNUSED(ring));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
int e1000_up(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	/* hardware has been reset, we need to reload some things */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	e1000_configure(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	clear_bit(__E1000_DOWN, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
		napi_enable(&adapter->napi);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
		e1000_irq_enable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
		netif_wake_queue(adapter->netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		/* fire a link change interrupt to start the watchdog */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		ew32(ICS, E1000_ICS_LSC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
 * e1000_power_up_phy - restore link in case the phy was powered down
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
 * @adapter: address of board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
 * The phy may be powered down to save power and turn off link when the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
 * driver is unloaded and wake on lan is not enabled (among others)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 * *** this routine MUST be followed by a call to e1000_reset ***
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
void e1000_power_up_phy(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	u16 mii_reg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	/* Just clear the power down bit to wake the phy back up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		/* according to the manual, the phy will retain its
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		 * settings across a power-down/up cycle */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		mii_reg &= ~MII_CR_POWER_DOWN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
static void e1000_power_down_phy(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	/* Power down the PHY so no link is implied when interface is down *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	 * The PHY cannot be powered down if any of the following is true *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	 * (a) WoL is enabled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	 * (b) AMT is active
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 * (c) SoL/IDER session is active */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	   hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		u16 mii_reg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		case e1000_82540:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		case e1000_82545:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		case e1000_ce4100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
				goto out;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
			goto out;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		mii_reg |= MII_CR_POWER_DOWN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		mdelay(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
out:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
void e1000_down(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	u32 rctl, tctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* disable receives in the hardware */	
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		/* flush and sleep below */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		netif_tx_disable(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	/* disable transmits in the hardware */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	tctl = er32(TCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	tctl &= ~E1000_TCTL_EN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	ew32(TCTL, tctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	/* flush both disables and wait for them to finish */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	msleep(10);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
		napi_disable(&adapter->napi);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		e1000_irq_disable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	 * Setting DOWN must be after irq_disable to prevent
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	 * a screaming interrupt.  Setting DOWN also prevents
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	 * timers and tasks from rescheduling.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	set_bit(__E1000_DOWN, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		del_timer_sync(&adapter->tx_fifo_stall_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		del_timer_sync(&adapter->watchdog_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		del_timer_sync(&adapter->phy_info_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	adapter->link_speed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	adapter->link_duplex = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		netif_carrier_off(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	e1000_clean_all_tx_rings(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	e1000_clean_all_rx_rings(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
static void e1000_reinit_safe(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		msleep(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	rtnl_lock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	e1000_up(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	rtnl_unlock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	clear_bit(__E1000_RESETTING, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
void e1000_reinit_locked(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	/* if rtnl_lock is not held the call path is bogus */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	ASSERT_RTNL();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	WARN_ON(in_interrupt());
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		msleep(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	e1000_up(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	clear_bit(__E1000_RESETTING, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
void e1000_reset(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	bool legacy_pba_adjust = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	u16 hwm;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	/* Repartition Pba for greater than 9k mtu
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	 * To take effect CTRL.RST is required.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	case e1000_82540:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		legacy_pba_adjust = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		pba = E1000_PBA_48K;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	case e1000_82545:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	case e1000_82545_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	case e1000_ce4100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		pba = E1000_PBA_48K;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		legacy_pba_adjust = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		pba = E1000_PBA_30K;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	case e1000_undefined:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	case e1000_num_macs:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	if (legacy_pba_adjust) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
			pba -= 8; /* allocate more FIFO for Tx */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		if (hw->mac_type == e1000_82547) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
			adapter->tx_fifo_head = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
			adapter->tx_fifo_size =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			atomic_set(&adapter->tx_fifo_stall, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		/* adjust PBA for jumbo frames */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		ew32(PBA, pba);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		/* To maintain wire speed transmits, the Tx FIFO should be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		 * large enough to accommodate two full transmit packets,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		 * the Rx FIFO should be large enough to accommodate at least
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		 * one full receive packet and is similarly rounded up and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		 * expressed in KB. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		pba = er32(PBA);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
		/* upper 16 bits has Tx packet buffer allocation size in KB */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		tx_space = pba >> 16;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		/* lower 16 bits has Rx packet buffer allocation size in KB */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		pba &= 0xffff;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		 * the tx fifo also stores 16 bytes of information about the tx
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		 * but don't include ethernet FCS because hardware appends it
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		min_tx_space = (hw->max_frame_size +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		                sizeof(struct e1000_tx_desc) -
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		                ETH_FCS_LEN) * 2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		min_tx_space = ALIGN(min_tx_space, 1024);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		min_tx_space >>= 10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		/* software strips receive CRC, so leave room for it */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		min_rx_space = hw->max_frame_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		min_rx_space = ALIGN(min_rx_space, 1024);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		min_rx_space >>= 10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
		/* If current Tx allocation is less than the min Tx FIFO size,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		 * and the min Tx FIFO size is less than the current Rx FIFO
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		 * allocation, take space away from current Rx allocation */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		if (tx_space < min_tx_space &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		    ((min_tx_space - tx_space) < pba)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
			pba = pba - (min_tx_space - tx_space);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
			/* PCI/PCIx hardware has PBA alignment constraints */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
			switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
			case e1000_82545 ... e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
				pba &= ~(E1000_PBA_8K - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
			default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
			/* if short on rx space, rx wins and must trump tx
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
			 * adjustment or use Early Receive if available */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			if (pba < min_rx_space)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
				pba = min_rx_space;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	ew32(PBA, pba);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	 * flow control settings:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	 * The high water mark must be low enough to fit one full frame
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	 * (or the size used for early receive) above it in the Rx FIFO.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	 * Set it to the lower of:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	 * - 90% of the Rx FIFO size, and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	 * - the full Rx FIFO size minus the early receive size (for parts
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	 * - the full Rx FIFO size minus one full frame
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	hwm = min(((pba << 10) * 9 / 10),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		  ((pba << 10) - hw->max_frame_size));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	hw->fc_low_water = hw->fc_high_water - 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	hw->fc_send_xon = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	hw->fc = hw->original_fc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	/* Allow time for pending master requests to run */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	e1000_reset_hw(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	if (hw->mac_type >= e1000_82544)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		ew32(WUC, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	if (e1000_init_hw(hw))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		e_dev_err("Hardware Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	e1000_update_mng_vlan(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	if (hw->mac_type >= e1000_82544 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	    hw->autoneg == 1 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		u32 ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
		/* clear phy power management bit if we are in gig only mode,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		 * which if enabled will attempt negotiation to 100Mb, which
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		 * can cause a loss of link at power off or driver unload */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		ctrl &= ~E1000_CTRL_SWDPIN3;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	e1000_reset_adaptive(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	e1000_phy_get_info(hw, &adapter->phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	e1000_release_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
 *  Dump the eeprom for users having checksum issues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	struct ethtool_eeprom eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	const struct ethtool_ops *ops = netdev->ethtool_ops;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	u8 *data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	u16 csum_old, csum_new = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	eeprom.len = ops->get_eeprom_len(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	eeprom.offset = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	data = kmalloc(eeprom.len, GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	if (!data) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		pr_err("Unable to allocate memory to dump EEPROM data\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	ops->get_eeprom(netdev, &eeprom, data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		csum_new += data[i] + (data[i + 1] << 8);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	csum_new = EEPROM_SUM - csum_new;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	pr_err("/*********************/\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	pr_err("Calculated              : 0x%04x\n", csum_new);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	pr_err("Offset    Values\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	pr_err("========  ======\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	pr_err("Include this output when contacting your support provider.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	pr_err("This is not a software error! Something bad happened to\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	pr_err("result in further problems, possibly loss of data,\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	pr_err("corruption or system hangs!\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	pr_err("which is invalid and requires you to set the proper MAC\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	pr_err("address manually before continuing to enable this network\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	pr_err("device. Please inspect the EEPROM dump and report the\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	pr_err("/*********************/\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	kfree(data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 * @pdev: PCI device information struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 * Return true if an adapter needs ioport resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
static int e1000_is_need_ioport(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	switch (pdev->device) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	case E1000_DEV_ID_82540EM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	case E1000_DEV_ID_82540EM_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	case E1000_DEV_ID_82540EP:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	case E1000_DEV_ID_82540EP_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	case E1000_DEV_ID_82540EP_LP:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	case E1000_DEV_ID_82541EI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	case E1000_DEV_ID_82541EI_MOBILE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	case E1000_DEV_ID_82541ER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	case E1000_DEV_ID_82541ER_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	case E1000_DEV_ID_82541GI:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	case E1000_DEV_ID_82541GI_LF:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	case E1000_DEV_ID_82541GI_MOBILE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	case E1000_DEV_ID_82544EI_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	case E1000_DEV_ID_82544EI_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	case E1000_DEV_ID_82544GC_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	case E1000_DEV_ID_82544GC_LOM:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	case E1000_DEV_ID_82545EM_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	case E1000_DEV_ID_82545EM_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	case E1000_DEV_ID_82546EB_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	case E1000_DEV_ID_82546EB_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		return true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		return false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
static const struct net_device_ops e1000_netdev_ops = {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	.ndo_open		= e1000_open,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	.ndo_stop		= e1000_close,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	.ndo_start_xmit		= e1000_xmit_frame,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	.ndo_get_stats		= e1000_get_stats,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	.ndo_set_rx_mode	= e1000_set_rx_mode,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	.ndo_set_mac_address	= e1000_set_mac,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	.ndo_tx_timeout 	= e1000_tx_timeout,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	.ndo_change_mtu		= e1000_change_mtu,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	.ndo_do_ioctl		= e1000_ioctl,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	.ndo_validate_addr	= eth_validate_addr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
#ifdef CONFIG_NET_POLL_CONTROLLER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	.ndo_poll_controller	= e1000_netpoll,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
 * e1000_init_hw_struct - initialize members of hw struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
 * @adapter: board private struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
 * @hw: structure used by e1000_hw.c
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
 * Factors out initialization of the e1000_hw struct to its own function
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
 * that can be called very early at init (just after struct allocation).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
 * Fields are initialized based on PCI device information and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
 * OS network device settings (MTU size).
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
 * Returns negative error codes if MAC type setup fails.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
static int e1000_init_hw_struct(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
				struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	/* PCI config space info */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	hw->vendor_id = pdev->vendor;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	hw->device_id = pdev->device;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	hw->subsystem_id = pdev->subsystem_device;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	hw->revision_id = pdev->revision;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	hw->max_frame_size = adapter->netdev->mtu +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	/* identify the MAC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	if (e1000_set_mac_type(hw)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		e_err(probe, "Unknown MAC Type\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		return -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	case e1000_82541:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	case e1000_82547:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	case e1000_82541_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	case e1000_82547_rev_2:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		hw->phy_init_script = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	e1000_set_media_type(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	e1000_get_bus_info(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	hw->wait_autoneg_complete = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	hw->tbi_compatibility_en = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	hw->adaptive_ifs = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	/* Copper options */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		hw->mdix = AUTO_ALL_MODES;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
		hw->disable_polarity_correction = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		hw->master_slave = E1000_MASTER_SLAVE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
 * e1000_probe - Device Initialization Routine
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
 * @pdev: PCI device information struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
 * @ent: entry in e1000_pci_tbl
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
 * Returns 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
 * e1000_probe initializes an adapter identified by a pci_dev structure.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
 * The OS initialization, configuring of the adapter private structure,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
 * and a hardware reset occur.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
static int __devinit e1000_probe(struct pci_dev *pdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
				 const struct pci_device_id *ent)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	struct net_device *netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	struct e1000_adapter *adapter;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	struct e1000_hw *hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	static int cards_found = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	int i, err, pci_using_dac;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	u16 eeprom_data = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	u16 tmp = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	int bars, need_ioport;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	/* do not allocate ioport bars when not needed */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	need_ioport = e1000_is_need_ioport(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	if (need_ioport) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		err = pci_enable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		err = pci_enable_device_mem(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		goto err_pci_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	pci_set_master(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	err = pci_save_state(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
		goto err_alloc_etherdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	err = -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	if (!netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
		goto err_alloc_etherdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	SET_NETDEV_DEV(netdev, &pdev->dev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	pci_set_drvdata(pdev, netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	adapter->netdev = netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	adapter->pdev = pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	adapter->msg_enable = (1 << debug) - 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	adapter->bars = bars;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	adapter->need_ioport = need_ioport;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	hw->back = adapter;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	err = -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	if (!hw->hw_addr)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		goto err_ioremap;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	if (adapter->need_ioport) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		for (i = BAR_1; i <= BAR_5; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
			if (pci_resource_len(pdev, i) == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
				continue;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
				hw->io_base = pci_resource_start(pdev, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	/* make ready for any if (hw->...) below */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	err = e1000_init_hw_struct(adapter, hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		goto err_sw_init;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	 * there is a workaround being applied below that limits
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	 * 64-bit DMA addresses to 64-bit hardware.  There are some
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	pci_using_dac = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	if ((hw->bus_type == e1000_bus_type_pcix) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		 * according to DMA-API-HOWTO, coherent calls will always
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		 * succeed if the set call did
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		pci_using_dac = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			pr_err("No usable DMA config, aborting\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
			goto err_dma;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	netdev->netdev_ops = &e1000_netdev_ops;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	e1000_set_ethtool_ops(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	netdev->watchdog_timeo = 5 * HZ;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	adapter->bd_number = cards_found;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	/* setup the private structure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	err = e1000_sw_init(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		goto err_sw_init;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	err = -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		ce4100_gbe_mdio_base_phy = pci_resource_start(pdev, BAR_1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		ce4100_gbe_mdio_base_virt = ioremap(ce4100_gbe_mdio_base_phy,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		                                pci_resource_len(pdev, BAR_1));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		if (!ce4100_gbe_mdio_base_virt)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			goto err_mdio_ioremap;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	if (hw->mac_type >= e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		netdev->features = NETIF_F_SG |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
				   NETIF_F_HW_CSUM |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
				   NETIF_F_HW_VLAN_TX |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
				   NETIF_F_HW_VLAN_RX |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
				   NETIF_F_HW_VLAN_FILTER;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	if ((hw->mac_type >= e1000_82544) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	   (hw->mac_type != e1000_82547))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		netdev->features |= NETIF_F_TSO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	if (pci_using_dac) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		netdev->features |= NETIF_F_HIGHDMA;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		netdev->vlan_features |= NETIF_F_HIGHDMA;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	netdev->vlan_features |= NETIF_F_TSO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	netdev->vlan_features |= NETIF_F_HW_CSUM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	netdev->vlan_features |= NETIF_F_SG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	/* initialize eeprom parameters */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	if (e1000_init_eeprom_params(hw)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		e_err(probe, "EEPROM initialization failed\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		goto err_eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	/* before reading the EEPROM, reset the controller to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	 * put the device in a known good starting state */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	e1000_reset_hw(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	/* make sure the EEPROM is good */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	if (e1000_validate_eeprom_checksum(hw) < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		e1000_dump_eeprom(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		 * set MAC address to all zeroes to invalidate and temporary
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		 * disable this device for the user. This blocks regular
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		 * traffic while still permitting ethtool ioctls from reaching
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		 * the hardware as well as allowing the user to run the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		 * interface after manually setting a hw addr using
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		 * `ip set address`
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		memset(hw->mac_addr, 0, netdev->addr_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		/* copy the MAC address out of the EEPROM */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		if (e1000_read_mac_addr(hw))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
			e_err(probe, "EEPROM Read Error\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	/* don't block initalization here due to bad MAC address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	if (!is_valid_ether_addr(netdev->perm_addr))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		e_err(probe, "Invalid MAC Address\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	init_timer(&adapter->tx_fifo_stall_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	init_timer(&adapter->watchdog_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	adapter->watchdog_timer.function = e1000_watchdog;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	adapter->watchdog_timer.data = (unsigned long) adapter;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	init_timer(&adapter->phy_info_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	adapter->phy_info_timer.function = e1000_update_phy_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	adapter->phy_info_timer.data = (unsigned long)adapter;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	INIT_WORK(&adapter->fifo_stall_task, e1000_82547_tx_fifo_stall_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	INIT_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	e1000_check_options(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	/* Initial Wake on LAN setting
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	 * If APM wake is enabled in the EEPROM,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	 * enable the ACPI Magic Packet filter
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	case e1000_82543:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		e1000_read_eeprom(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	case e1000_82546:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	case e1000_82546_rev_3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			e1000_read_eeprom(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		/* Fall Through */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		e1000_read_eeprom(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	if (eeprom_data & eeprom_apme_mask)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		adapter->eeprom_wol |= E1000_WUFC_MAG;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	/* now that we have the eeprom settings, apply the special cases
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	 * where the eeprom may be wrong or the board simply won't support
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	 * wake on lan on a particular port */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	switch (pdev->device) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	case E1000_DEV_ID_82546GB_PCIE:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		adapter->eeprom_wol = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	case E1000_DEV_ID_82546EB_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	case E1000_DEV_ID_82546GB_FIBER:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		/* Wake events only supported on port A for dual fiber
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		 * regardless of eeprom setting */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
			adapter->eeprom_wol = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		/* if quad port adapter, disable WoL on all but port A */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		if (global_quad_port_a != 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
			adapter->eeprom_wol = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
			adapter->quad_port_a = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		/* Reset for multiple quad port adapters */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		if (++global_quad_port_a == 4)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			global_quad_port_a = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	/* initialize the wol settings based on the eeprom settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	adapter->wol = adapter->eeprom_wol;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	/* Auto detect PHY address */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	if (hw->mac_type == e1000_ce4100) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		for (i = 0; i < 32; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
			hw->phy_addr = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			if (tmp == 0 || tmp == 0xFF) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
				if (i == 31)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
					goto err_eeprom;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
				continue;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			} else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	/* reset the hardware with the new settings */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
 	// offer device to EtherCAT master module
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	if (adapter->ecdev) {
2582
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2471
diff changeset
  1212
		err = ecdev_open(adapter->ecdev);
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2471
diff changeset
  1213
		if (err) {
2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
			ecdev_withdraw(adapter->ecdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			goto err_register;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		strcpy(netdev->name, "eth%d");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		err = register_netdev(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
			goto err_register;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	/* print bus type/speed/width info */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	       netdev->dev_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		/* carrier off reporting is important to ethtool even BEFORE open */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		netif_carrier_off(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	cards_found++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
err_register:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
err_eeprom:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	e1000_phy_hw_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	if (hw->flash_address)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		iounmap(hw->flash_address);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	kfree(adapter->tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	kfree(adapter->rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
err_dma:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
err_sw_init:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
err_mdio_ioremap:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	iounmap(ce4100_gbe_mdio_base_virt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	iounmap(hw->hw_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
err_ioremap:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	free_netdev(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
err_alloc_etherdev:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	pci_release_selected_regions(pdev, bars);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
err_pci_reg:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	pci_disable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * e1000_remove - Device Removal Routine
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 * @pdev: PCI device information struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 * e1000_remove is called by the PCI subsystem to alert the driver
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
 * that it should release a PCI device.  The could be caused by a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
 * Hot-Plug event, or because the driver is going to be removed from
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
 * memory.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
static void __devexit e1000_remove(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	set_bit(__E1000_DOWN, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		del_timer_sync(&adapter->tx_fifo_stall_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		del_timer_sync(&adapter->watchdog_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		del_timer_sync(&adapter->phy_info_timer);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	cancel_work_sync(&adapter->reset_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	e1000_release_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		ecdev_close(adapter->ecdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		ecdev_withdraw(adapter->ecdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		unregister_netdev(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
	e1000_phy_hw_reset(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	kfree(adapter->tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	kfree(adapter->rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	iounmap(hw->hw_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	if (hw->flash_address)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		iounmap(hw->flash_address);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	pci_release_selected_regions(pdev, adapter->bars);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	free_netdev(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	pci_disable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * @adapter: board private structure to initialize
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 * e1000_sw_init initializes the Adapter private data structure.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 * e1000_init_hw_struct MUST be called before this function
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	adapter->num_tx_queues = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	adapter->num_rx_queues = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	if (e1000_alloc_queues(adapter)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		e_err(probe, "Unable to allocate memory for queues\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	/* Explicitly disable IRQ since the NIC can be in any state. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	e1000_irq_disable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	spin_lock_init(&adapter->stats_lock);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	set_bit(__E1000_DOWN, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
 * e1000_alloc_queues - Allocate memory for all rings
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
 * @adapter: board private structure to initialize
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 * We allocate one ring per queue at run-time since we don't know the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 * number of queues at compile-time.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	if (!adapter->tx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	if (!adapter->rx_ring) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		kfree(adapter->tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
 * e1000_open - Called when a network interface is made active
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 * Returns 0 on success, negative value on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 * The open entry point is called when a network interface is made
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
 * active by the system (IFF_UP).  At this point all resources needed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
 * for transmit and receive operations are allocated, the interrupt
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
 * handler is registered with the OS, the watchdog timer is started,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
 * and the stack is notified that the interface is ready.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
static int e1000_open(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	int err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	/* disallow open during test */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	if (test_bit(__E1000_TESTING, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		return -EBUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	netif_carrier_off(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	/* allocate transmit descriptors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	err = e1000_setup_all_tx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		goto err_setup_tx;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	/* allocate receive descriptors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	err = e1000_setup_all_rx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		goto err_setup_rx;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	e1000_power_up_phy(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	if ((hw->mng_cookie.status &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		e1000_update_mng_vlan(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	/* before we allocate an interrupt, we must be ready to handle it.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	 * as soon as we call pci_request_irq, so we have to setup our
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	 * clean_rx handler before we do so.  */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	e1000_configure(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	err = e1000_request_irq(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		goto err_req_irq;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	/* From here on the code is the same as e1000_up() */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	clear_bit(__E1000_DOWN, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
2469
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1427
	if (!adapter->ecdev) {
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1428
		napi_enable(&adapter->napi);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1429
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1430
		e1000_irq_enable(adapter);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1431
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1432
		netif_start_queue(netdev);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2386
diff changeset
  1433
	}
2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	/* fire a link status change interrupt to start the watchdog */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	ew32(ICS, E1000_ICS_LSC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
err_req_irq:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	e1000_power_down_phy(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	e1000_free_all_rx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
err_setup_rx:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	e1000_free_all_tx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
err_setup_tx:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
 * e1000_close - Disables a network interface
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
 * Returns 0, this is not allowed to fail
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
 * The close entry point is called when an interface is de-activated
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
 * by the OS.  The hardware is still under the drivers control, but
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
 * needs to be disabled.  A global MAC reset is issued to stop the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
 * hardware, and all transmit and receive resources are freed.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
static int e1000_close(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	e1000_power_down_phy(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	e1000_free_irq(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	e1000_free_all_tx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	e1000_free_all_rx_resources(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	/* kill manageability vlan ID if supported, but not if a vlan with
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	 * the same ID is registered on the host OS (let 8021q kill it) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	if ((hw->mng_cookie.status &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	     !(adapter->vlgrp &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
 * @adapter: address of board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
 * @start: address of beginning of memory
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
 * @len: length of memory
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
				  unsigned long len)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	unsigned long begin = (unsigned long)start;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	unsigned long end = begin + len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	/* First rev 82545 and 82546 need to not allow any memory
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	 * write location to cross 64k boundary due to errata 23 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	if (hw->mac_type == e1000_82545 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	    hw->mac_type == e1000_ce4100 ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	    hw->mac_type == e1000_82546) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	return true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
 * @txdr:    tx descriptor ring (for a specific queue) to setup
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
 * Return 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
				    struct e1000_tx_ring *txdr)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	int size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	size = sizeof(struct e1000_buffer) * txdr->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	txdr->buffer_info = vzalloc(size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	if (!txdr->buffer_info) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		      "ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	/* round up to nearest 4K */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	txdr->size = ALIGN(txdr->size, 4096);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
					GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	if (!txdr->desc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
setup_tx_desc_die:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		vfree(txdr->buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		      "ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	/* Fix for errata 23, can't cross 64kB boundary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		void *olddesc = txdr->desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		dma_addr_t olddma = txdr->dma;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		      txdr->size, txdr->desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		/* Try again, without freeing the previous */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
						&txdr->dma, GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		/* Failed allocation, critical failure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		if (!txdr->desc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
			goto setup_tx_desc_die;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
			/* give up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
					  txdr->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
			e_err(probe, "Unable to allocate aligned memory "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
			      "for the transmit descriptor ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
			vfree(txdr->buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
			return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
			/* Free old allocation, new allocation was successful */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	memset(txdr->desc, 0, txdr->size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	txdr->next_to_use = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	txdr->next_to_clean = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 * 				  (Descriptors) for all queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
 * Return 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	int i, err = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	for (i = 0; i < adapter->num_tx_queues; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
			for (i-- ; i >= 0; i--)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
				e1000_free_tx_resources(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
							&adapter->tx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
 * Configure the Tx unit of the MAC after a reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
static void e1000_configure_tx(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	u64 tdba;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	u32 tdlen, tctl, tipg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	u32 ipgr1, ipgr2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	/* Setup the HW Tx Head and Tail descriptor pointers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	switch (adapter->num_tx_queues) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	case 1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		tdba = adapter->tx_ring[0].dma;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		tdlen = adapter->tx_ring[0].count *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
			sizeof(struct e1000_tx_desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		ew32(TDLEN, tdlen);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		ew32(TDBAH, (tdba >> 32));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		ew32(TDT, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		ew32(TDH, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	/* Set the default values for the Tx Inter Packet Gap timer */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	if ((hw->media_type == e1000_media_type_fiber ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	     hw->media_type == e1000_media_type_internal_serdes))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	case e1000_82542_rev2_0:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	case e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		tipg = DEFAULT_82542_TIPG_IPGT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	ew32(TIPG, tipg);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	/* Set the Tx Interrupt Delay register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	ew32(TIDV, adapter->tx_int_delay);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	if (hw->mac_type >= e1000_82540)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		ew32(TADV, adapter->tx_abs_int_delay);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	/* Program the Transmit Control Register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	tctl = er32(TCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	tctl &= ~E1000_TCTL_CT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	e1000_config_collision_dist(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	/* Setup Transmit Descriptor Settings for eop descriptor */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	/* only set IDE if we are delaying interrupts using the timers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	if (adapter->tx_int_delay)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	if (hw->mac_type < e1000_82543)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	/* Cache if we're 82544 running in PCI-X because we'll
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	 * need this to apply a workaround later in the send path. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	if (hw->mac_type == e1000_82544 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	    hw->bus_type == e1000_bus_type_pcix)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		adapter->pcix_82544 = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	ew32(TCTL, tctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
 * Returns 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
				    struct e1000_rx_ring *rxdr)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	int size, desc_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	size = sizeof(struct e1000_buffer) * rxdr->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	rxdr->buffer_info = vzalloc(size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	if (!rxdr->buffer_info) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		      "ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	desc_len = sizeof(struct e1000_rx_desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	/* Round up to nearest 4K */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	rxdr->size = rxdr->count * desc_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	rxdr->size = ALIGN(rxdr->size, 4096);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
					GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	if (!rxdr->desc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		      "ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
setup_rx_desc_die:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		vfree(rxdr->buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		return -ENOMEM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	/* Fix for errata 23, can't cross 64kB boundary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		void *olddesc = rxdr->desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		dma_addr_t olddma = rxdr->dma;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		      rxdr->size, rxdr->desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		/* Try again, without freeing the previous */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
						&rxdr->dma, GFP_KERNEL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		/* Failed allocation, critical failure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		if (!rxdr->desc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			e_err(probe, "Unable to allocate memory for the Rx "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			      "descriptor ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
			goto setup_rx_desc_die;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
			/* give up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
					  rxdr->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
			e_err(probe, "Unable to allocate aligned memory for "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
			      "the Rx descriptor ring\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
			goto setup_rx_desc_die;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
			/* Free old allocation, new allocation was successful */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
					  olddma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	memset(rxdr->desc, 0, rxdr->size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
	rxdr->next_to_clean = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	rxdr->next_to_use = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	rxdr->rx_skb_top = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 * 				  (Descriptors) for all queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 * Return 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	int i, err = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	for (i = 0; i < adapter->num_rx_queues; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
			for (i-- ; i >= 0; i--)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
				e1000_free_rx_resources(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
							&adapter->rx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
 * e1000_setup_rctl - configure the receive control registers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 * @adapter: Board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
static void e1000_setup_rctl(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	u32 rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	if (hw->tbi_compatibility_on == 1)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		rctl |= E1000_RCTL_SBP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		rctl &= ~E1000_RCTL_SBP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		rctl &= ~E1000_RCTL_LPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		rctl |= E1000_RCTL_LPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	/* Setup buffer sizes */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	rctl &= ~E1000_RCTL_SZ_4096;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	rctl |= E1000_RCTL_BSEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
	switch (adapter->rx_buffer_len) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		case E1000_RXBUFFER_2048:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
			rctl |= E1000_RCTL_SZ_2048;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
			rctl &= ~E1000_RCTL_BSEX;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		case E1000_RXBUFFER_4096:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			rctl |= E1000_RCTL_SZ_4096;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		case E1000_RXBUFFER_8192:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
			rctl |= E1000_RCTL_SZ_8192;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		case E1000_RXBUFFER_16384:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			rctl |= E1000_RCTL_SZ_16384;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
 * Configure the Rx unit of the MAC after a reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
static void e1000_configure_rx(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	u64 rdba;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	u32 rdlen, rctl, rxcsum;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		rdlen = adapter->rx_ring[0].count *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		        sizeof(struct e1000_rx_desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		rdlen = adapter->rx_ring[0].count *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		        sizeof(struct e1000_rx_desc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		adapter->clean_rx = e1000_clean_rx_irq;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	/* disable receives while setting up the descriptors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	/* set the Receive Delay Timer Register */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	ew32(RDTR, adapter->rx_int_delay);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	if (hw->mac_type >= e1000_82540) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		ew32(RADV, adapter->rx_abs_int_delay);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		if (adapter->itr_setting != 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			ew32(ITR, 1000000000 / (adapter->itr * 256));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	 * the Base and Length of the Rx Descriptor Ring */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	switch (adapter->num_rx_queues) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	case 1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
		rdba = adapter->rx_ring[0].dma;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
		ew32(RDLEN, rdlen);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
		ew32(RDBAH, (rdba >> 32));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		ew32(RDT, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		ew32(RDH, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	if (hw->mac_type >= e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		rxcsum = er32(RXCSUM);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
		if (adapter->rx_csum)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
			rxcsum |= E1000_RXCSUM_TUOFL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
			/* don't need to clear IPPCSE as it defaults to 0 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
			rxcsum &= ~E1000_RXCSUM_TUOFL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		ew32(RXCSUM, rxcsum);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	/* Enable Receives */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
 * e1000_free_tx_resources - Free Tx Resources per Queue
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
 * @tx_ring: Tx descriptor ring for a specific queue
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
 * Free all transmit software resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
				    struct e1000_tx_ring *tx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	e1000_clean_tx_ring(adapter, tx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	vfree(tx_ring->buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	tx_ring->buffer_info = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
			  tx_ring->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	tx_ring->desc = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
 * Free all transmit software resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	for (i = 0; i < adapter->num_tx_queues; i++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
					     struct e1000_buffer *buffer_info)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	if (buffer_info->dma) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		if (buffer_info->mapped_as_page)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
				       buffer_info->length, DMA_TO_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
					 buffer_info->length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
					 DMA_TO_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	if (buffer_info->skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		dev_kfree_skb_any(buffer_info->skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	buffer_info->time_stamp = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	/* buffer_info must be completely set up in the transmit path */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
 * e1000_clean_tx_ring - Free Tx Buffers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
 * @tx_ring: ring to be cleaned
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
				struct e1000_tx_ring *tx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	unsigned long size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	/* Free all the Tx ring sk_buffs */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	for (i = 0; i < tx_ring->count; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	size = sizeof(struct e1000_buffer) * tx_ring->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	memset(tx_ring->buffer_info, 0, size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	/* Zero out the descriptor ring */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	memset(tx_ring->desc, 0, tx_ring->size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	tx_ring->next_to_use = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	tx_ring->next_to_clean = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	tx_ring->last_tx_tso = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	writel(0, hw->hw_addr + tx_ring->tdh);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	writel(0, hw->hw_addr + tx_ring->tdt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	for (i = 0; i < adapter->num_tx_queues; i++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 * e1000_free_rx_resources - Free Rx Resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
 * @rx_ring: ring to clean the resources from
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
 * Free all receive software resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
				    struct e1000_rx_ring *rx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	e1000_clean_rx_ring(adapter, rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	vfree(rx_ring->buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	rx_ring->buffer_info = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
			  rx_ring->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	rx_ring->desc = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
 * Free all receive software resources
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	for (i = 0; i < adapter->num_rx_queues; i++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
 * @rx_ring: ring to free buffers from
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
				struct e1000_rx_ring *rx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	unsigned long size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	/* Free all the Rx ring sk_buffs */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	for (i = 0; i < rx_ring->count; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		if (buffer_info->dma &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		    adapter->clean_rx == e1000_clean_rx_irq) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
			dma_unmap_single(&pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			                 buffer_info->length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
					 DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		} else if (buffer_info->dma &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			dma_unmap_page(&pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
				       buffer_info->length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
				       DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		if (buffer_info->page) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			put_page(buffer_info->page);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			buffer_info->page = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		if (buffer_info->skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			dev_kfree_skb(buffer_info->skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
			buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	/* there also may be some cached data from a chained receive */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	if (rx_ring->rx_skb_top) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
		dev_kfree_skb(rx_ring->rx_skb_top);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		rx_ring->rx_skb_top = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	size = sizeof(struct e1000_buffer) * rx_ring->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	memset(rx_ring->buffer_info, 0, size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	/* Zero out the descriptor ring */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	memset(rx_ring->desc, 0, rx_ring->size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	rx_ring->next_to_clean = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	rx_ring->next_to_use = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	writel(0, hw->hw_addr + rx_ring->rdh);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
	writel(0, hw->hw_addr + rx_ring->rdt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	for (i = 0; i < adapter->num_rx_queues; i++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
 * and memory write and invalidate disabled for certain operations
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	u32 rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	e1000_pci_clear_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	rctl |= E1000_RCTL_RST;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	mdelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	if (!adapter->ecdev && netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
		e1000_clean_all_rx_rings(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	u32 rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	rctl &= ~E1000_RCTL_RST;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	mdelay(5);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		e1000_pci_set_mwi(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	if (!adapter->netdev && netif_running(netdev)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		/* No need to loop, because 82542 supports only 1 queue */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		e1000_configure_rx(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
			/* fill rx ring completely! */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
			adapter->alloc_rx_buf(adapter, ring, ring->count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
			/* this one leaves the last ring element unallocated! */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
 * e1000_set_mac - Change the Ethernet Address of the NIC
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
 * @p: pointer to an address structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
 * Returns 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
static int e1000_set_mac(struct net_device *netdev, void *p)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	struct sockaddr *addr = p;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	if (!is_valid_ether_addr(addr->sa_data))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		return -EADDRNOTAVAIL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	/* 82542 2.0 needs to be in reset to write receive address registers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		e1000_enter_82542_rst(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	e1000_rar_set(hw, hw->mac_addr, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
		e1000_leave_82542_rst(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
 * The set_rx_mode entry point is called whenever the unicast or multicast
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
 * address lists or the network interface flags are updated. This routine is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
 * responsible for configuring the hardware for proper unicast, multicast,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
 * promiscuous mode, and all-multi behavior.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
static void e1000_set_rx_mode(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	struct netdev_hw_addr *ha;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	bool use_uc = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	u32 rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	u32 hash_value;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	int i, rar_entries = E1000_RAR_ENTRIES;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	if (!mcarray) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
		e_err(probe, "memory allocation failed\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	/* Check for Promiscuous and All Multicast modes */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	if (netdev->flags & IFF_PROMISC) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
		rctl &= ~E1000_RCTL_VFE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
		if (netdev->flags & IFF_ALLMULTI)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
			rctl |= E1000_RCTL_MPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
		else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
			rctl &= ~E1000_RCTL_MPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
		/* Enable VLAN filter if there is a VLAN */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
		if (adapter->vlgrp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
			rctl |= E1000_RCTL_VFE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	if (netdev_uc_count(netdev) > rar_entries - 1) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
		rctl |= E1000_RCTL_UPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	} else if (!(netdev->flags & IFF_PROMISC)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		rctl &= ~E1000_RCTL_UPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
		use_uc = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	/* 82542 2.0 needs to be in reset to write receive address registers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
		e1000_enter_82542_rst(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	/* load the first 14 addresses into the exact filters 1-14. Unicast
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	 * addresses take precedence to avoid disabling unicast filtering
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	 * when possible.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	 * RAR 0 is used for the station MAC address
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	 * if there are not 14 addresses, go ahead and clear the filters
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	i = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	if (use_uc)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
		netdev_for_each_uc_addr(ha, netdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
			if (i == rar_entries)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			e1000_rar_set(hw, ha->addr, i++);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	netdev_for_each_mc_addr(ha, netdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		if (i == rar_entries) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			/* load any remaining addresses into the hash table */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			u32 hash_reg, hash_bit, mta;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
			hash_reg = (hash_value >> 5) & 0x7F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
			hash_bit = hash_value & 0x1F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
			mta = (1 << hash_bit);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
			mcarray[hash_reg] |= mta;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
			e1000_rar_set(hw, ha->addr, i++);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	for (; i < rar_entries; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	/* write the hash table completely, write from bottom to avoid
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	 * both stupid write combining chipsets, and flushing each write */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		 * If we are on an 82544 has an errata where writing odd
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		 * offsets overwrites the previous even offset, but writing
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		 * backwards over the range solves the issue by always
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		 * writing the odd offset first
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	if (hw->mac_type == e1000_82542_rev2_0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		e1000_leave_82542_rst(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	kfree(mcarray);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
/* Need to wait a few seconds after link up to get diagnostic information from
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
 * the phy */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
static void e1000_update_phy_info(unsigned long data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	schedule_work(&adapter->phy_info_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
static void e1000_update_phy_info_task(struct work_struct *work)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	struct e1000_adapter *adapter = container_of(work,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	                                             struct e1000_adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	                                             phy_info_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	rtnl_lock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	e1000_phy_get_info(hw, &adapter->phy_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	rtnl_unlock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
 * e1000_82547_tx_fifo_stall - Timer Call-back
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
 * @data: pointer to adapter cast into an unsigned long
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
static void e1000_82547_tx_fifo_stall(unsigned long data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	schedule_work(&adapter->fifo_stall_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
 * e1000_82547_tx_fifo_stall_task - task to complete work
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
 * @work: work struct contained inside adapter struct
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	struct e1000_adapter *adapter = container_of(work,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	                                             struct e1000_adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	                                             fifo_stall_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	u32 tctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	rtnl_lock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	if (atomic_read(&adapter->tx_fifo_stall)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		if ((er32(TDT) == er32(TDH)) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		   (er32(TDFT) == er32(TDFH)) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		   (er32(TDFTS) == er32(TDFHS))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			tctl = er32(TCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
			ew32(TDFT, adapter->tx_head_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			ew32(TDFH, adapter->tx_head_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
			ew32(TDFTS, adapter->tx_head_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
			ew32(TDFHS, adapter->tx_head_addr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
			ew32(TCTL, tctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
			adapter->tx_fifo_head = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
			atomic_set(&adapter->tx_fifo_stall, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
			if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
				netif_wake_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
			if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	rtnl_unlock();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
bool e1000_has_link(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	bool link_active = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	/* get_link_status is set on LSC (link status) interrupt or
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	 * rx sequence error interrupt.  get_link_status will stay
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	 * false until the e1000_check_for_link establishes link
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	 * for copper adapters ONLY
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	switch (hw->media_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	case e1000_media_type_copper:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		if (hw->get_link_status) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
			e1000_check_for_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
			link_active = !hw->get_link_status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
			link_active = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	case e1000_media_type_fiber:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		e1000_check_for_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	case e1000_media_type_internal_serdes:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		e1000_check_for_link(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		link_active = hw->serdes_has_link;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	return link_active;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
 * e1000_watchdog - Timer Call-back
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
 * @data: pointer to adapter cast into an unsigned long
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
static void e1000_watchdog(unsigned long data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
	struct e1000_tx_ring *txdr = adapter->tx_ring;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	u32 link, tctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	link = e1000_has_link(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		goto link_up;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	if (link) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
			u32 ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			bool txb2b __attribute__ ((unused)) = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
			/* update snapshot of PHY registers on LSC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
			e1000_get_speed_and_duplex(hw,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
			                           &adapter->link_speed,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			                           &adapter->link_duplex);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
			ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
			pr_info("%s NIC Link is Up %d Mbps %s, "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
				"Flow Control: %s\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
				netdev->name,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
				adapter->link_speed,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
				adapter->link_duplex == FULL_DUPLEX ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
				"Full Duplex" : "Half Duplex",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
				E1000_CTRL_TFCE) ? "TX" : "None")));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			/* adjust timeout factor according to speed/duplex */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
			adapter->tx_timeout_factor = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
			switch (adapter->link_speed) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
			case SPEED_10:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
				txb2b = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
				adapter->tx_timeout_factor = 16;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
			case SPEED_100:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
				txb2b = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
				/* maybe add some timeout factor ? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
			/* enable transmits in the hardware */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
			tctl = er32(TCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
			tctl |= E1000_TCTL_EN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
			ew32(TCTL, tctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
				ecdev_set_link(adapter->ecdev, 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
				netif_carrier_on(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
				if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
					mod_timer(&adapter->phy_info_timer,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
							round_jiffies(jiffies + 2 * HZ));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			adapter->smartspeed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			adapter->link_speed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			adapter->link_duplex = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			pr_info("%s NIC Link is Down\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
				netdev->name);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
				ecdev_set_link(adapter->ecdev, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
				netif_carrier_off(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
				if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
					mod_timer(&adapter->phy_info_timer,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
							round_jiffies(jiffies + 2 * HZ));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
		e1000_smartspeed(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
link_up:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
	e1000_update_stats(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	adapter->tpt_old = adapter->stats.tpt;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	adapter->colc_old = adapter->stats.colc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	adapter->gorcl_old = adapter->stats.gorcl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	adapter->gotcl_old = adapter->stats.gotcl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	e1000_update_adaptive(hw);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
			/* We've lost link, so the controller stops DMA,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
			 * but we've got queued Tx work that's never going
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
			 * to get done, so reset controller to flush Tx.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			 * (Do the reset outside of interrupt context). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
			adapter->tx_timeout_count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
			schedule_work(&adapter->reset_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
			/* return immediately since reset is imminent */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
			return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	/* Simple mode for Interrupt Throttle Rate (ITR) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		 * Total asymmetrical Tx or Rx gets ITR=8000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		 * everyone else is between 2000-8000.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
		u32 dif = (adapter->gotcl > adapter->gorcl ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			    adapter->gotcl - adapter->gorcl :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			    adapter->gorcl - adapter->gotcl) / 10000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
		ew32(ITR, 1000000000 / (itr * 256));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	/* Cause software interrupt to ensure rx ring is cleaned */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
	ew32(ICS, E1000_ICS_RXDMT0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	/* Force detection of hung controller every watchdog period */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		adapter->detect_tx_hung = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	/* Reset the timer */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
			mod_timer(&adapter->watchdog_timer,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
			          round_jiffies(jiffies + 2 * HZ));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
enum latency_range {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	lowest_latency = 0,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	low_latency = 1,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	bulk_latency = 2,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	latency_invalid = 255
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
};
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
 * e1000_update_itr - update the dynamic ITR value based on statistics
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
 * @adapter: pointer to adapter
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
 * @itr_setting: current adapter->itr
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
 * @packets: the number of packets during this measurement interval
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
 * @bytes: the number of bytes during this measurement interval
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
 *      Stores a new ITR value based on packets and byte
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
 *      counts during the last interrupt.  The advantage of per interrupt
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
 *      computation is faster updates and more accurate ITR for the current
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
 *      traffic pattern.  Constants in this function were computed
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
 *      based on theoretical maximum wire speed and thresholds were set based
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
 *      on testing data as well as attempting to minimize response time
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
 *      while increasing bulk throughput.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
 *      this functionality is controlled by the InterruptThrottleRate module
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
 *      parameter (see e1000_param.c)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
				     u16 itr_setting, int packets, int bytes)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	unsigned int retval = itr_setting;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	if (unlikely(hw->mac_type < e1000_82540))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		goto update_itr_done;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	if (packets == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		goto update_itr_done;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	switch (itr_setting) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	case lowest_latency:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
		/* jumbo frames get bulk treatment*/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		if (bytes/packets > 8000)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
			retval = bulk_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		else if ((packets < 5) && (bytes > 512))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			retval = low_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	case low_latency:  /* 50 usec aka 20000 ints/s */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
		if (bytes > 10000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
			/* jumbo frames need bulk latency setting */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
			if (bytes/packets > 8000)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
				retval = bulk_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			else if ((packets < 10) || ((bytes/packets) > 1200))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
				retval = bulk_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
			else if ((packets > 35))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
				retval = lowest_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		} else if (bytes/packets > 2000)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
			retval = bulk_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		else if (packets <= 2 && bytes < 512)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
			retval = lowest_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	case bulk_latency: /* 250 usec aka 4000 ints/s */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		if (bytes > 25000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
			if (packets > 35)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
				retval = low_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		} else if (bytes < 6000) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
			retval = low_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
update_itr_done:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	return retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
static void e1000_set_itr(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	u16 current_itr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	u32 new_itr = adapter->itr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	if (unlikely(hw->mac_type < e1000_82540))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	if (unlikely(adapter->link_speed != SPEED_1000)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		current_itr = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		new_itr = 4000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		goto set_itr_now;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	adapter->tx_itr = e1000_update_itr(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	                            adapter->tx_itr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	                            adapter->total_tx_packets,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	                            adapter->total_tx_bytes);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		adapter->tx_itr = low_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	adapter->rx_itr = e1000_update_itr(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	                            adapter->rx_itr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	                            adapter->total_rx_packets,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	                            adapter->total_rx_bytes);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		adapter->rx_itr = low_latency;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	switch (current_itr) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	/* counts and packets in update_itr are dependent on these numbers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	case lowest_latency:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		new_itr = 70000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	case low_latency:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		new_itr = 20000; /* aka hwitr = ~200 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	case bulk_latency:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		new_itr = 4000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
set_itr_now:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	if (new_itr != adapter->itr) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		/* this attempts to bias the interrupt rate towards Bulk
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		 * by adding intermediate steps when interrupt rate is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		 * increasing */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
		new_itr = new_itr > adapter->itr ?
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		             min(adapter->itr + (new_itr >> 2), new_itr) :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
		             new_itr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		adapter->itr = new_itr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		ew32(ITR, 1000000000 / (new_itr * 256));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
#define E1000_TX_FLAGS_CSUM		0x00000001
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
#define E1000_TX_FLAGS_VLAN		0x00000002
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
#define E1000_TX_FLAGS_TSO		0x00000004
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
#define E1000_TX_FLAGS_IPV4		0x00000008
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
#define E1000_TX_FLAGS_VLAN_SHIFT	16
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
static int e1000_tso(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	struct e1000_context_desc *context_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	u32 cmd_length = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	u16 ipcse = 0, tucse, mss;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	int err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	if (skb_is_gso(skb)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		if (skb_header_cloned(skb)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
				return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		mss = skb_shinfo(skb)->gso_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		if (skb->protocol == htons(ETH_P_IP)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			struct iphdr *iph = ip_hdr(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			iph->tot_len = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			iph->check = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
								 iph->daddr, 0,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
								 IPPROTO_TCP,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
								 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
			cmd_length = E1000_TXD_CMD_IP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
			ipcse = skb_transport_offset(skb) - 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
			ipv6_hdr(skb)->payload_len = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
			tcp_hdr(skb)->check =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
						 &ipv6_hdr(skb)->daddr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
						 0, IPPROTO_TCP, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
			ipcse = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		ipcss = skb_network_offset(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		tucss = skb_transport_offset(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		tucse = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		i = tx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
		buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		context_desc->upper_setup.tcp_fields.tucss = tucss;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		context_desc->upper_setup.tcp_fields.tucso = tucso;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		buffer_info->time_stamp = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
		buffer_info->next_to_watch = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		if (++i == tx_ring->count) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		tx_ring->next_to_use = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
		return true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	return false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
static bool e1000_tx_csum(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	struct e1000_context_desc *context_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	u8 css;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	u32 cmd_len = E1000_TXD_CMD_DEXT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	if (skb->ip_summed != CHECKSUM_PARTIAL)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		return false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	switch (skb->protocol) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	case cpu_to_be16(ETH_P_IP):
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
			cmd_len |= E1000_TXD_CMD_TCP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	case cpu_to_be16(ETH_P_IPV6):
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		/* XXX not handling all IPV6 headers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
			cmd_len |= E1000_TXD_CMD_TCP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		if (unlikely(net_ratelimit()))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
			e_warn(drv, "checksum_partial proto=%x!\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
			       skb->protocol);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	css = skb_checksum_start_offset(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	i = tx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
	context_desc->lower_setup.ip_config = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	context_desc->upper_setup.tcp_fields.tucss = css;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	context_desc->upper_setup.tcp_fields.tucso =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		css + skb->csum_offset;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	context_desc->upper_setup.tcp_fields.tucse = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	context_desc->tcp_seg_setup.data = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	buffer_info->time_stamp = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	buffer_info->next_to_watch = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	if (unlikely(++i == tx_ring->count)) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	tx_ring->next_to_use = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	return true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
#define E1000_MAX_TXD_PWR	12
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
static int e1000_tx_map(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
			struct e1000_tx_ring *tx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
			struct sk_buff *skb, unsigned int first,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
			unsigned int max_per_txd, unsigned int nr_frags,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
			unsigned int mss)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	unsigned int len = skb_headlen(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	unsigned int offset = 0, size, count = 0, i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	unsigned int f;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	i = tx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	while (len) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		size = min(len, max_per_txd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		/* Workaround for Controller erratum --
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
		 * descriptor for non-tso packet in a linear SKB that follows a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		 * tso gets written back prematurely before the data is fully
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		 * DMA'd to the controller */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
		if (!skb->data_len && tx_ring->last_tx_tso &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		    !skb_is_gso(skb)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
			tx_ring->last_tx_tso = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
			size -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		/* Workaround for premature desc write-backs
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		 * in TSO mode.  Append 4-byte sentinel desc */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		if (unlikely(mss && !nr_frags && size == len && size > 8))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			size -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		/* work-around for errata 10 and it applies
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		 * to all controllers in PCI-X mode
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		 * The fix is to make sure that the first descriptor of a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		                (size > 2015) && count == 0))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		        size = 2015;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		 * terminating buffers within evenly-aligned dwords. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		if (unlikely(adapter->pcix_82544 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		   size > 4))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
			size -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		buffer_info->length = size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		/* set time_stamp *before* dma to help avoid a possible race */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		buffer_info->time_stamp = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		buffer_info->mapped_as_page = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		buffer_info->dma = dma_map_single(&pdev->dev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
						  skb->data + offset,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
						  size,	DMA_TO_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
			goto dma_error;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		buffer_info->next_to_watch = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		len -= size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		offset += size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		if (len) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
			i++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
			if (unlikely(i == tx_ring->count))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
				i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	for (f = 0; f < nr_frags; f++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		struct skb_frag_struct *frag;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		frag = &skb_shinfo(skb)->frags[f];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		len = frag->size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		offset = frag->page_offset;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		while (len) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
			i++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
			if (unlikely(i == tx_ring->count))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
				i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
			buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
			size = min(len, max_per_txd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
			/* Workaround for premature desc write-backs
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
			 * in TSO mode.  Append 4-byte sentinel desc */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
				size -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
			/* Workaround for potential 82544 hang in PCI-X.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
			 * Avoid terminating buffers within evenly-aligned
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
			 * dwords. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
			if (unlikely(adapter->pcix_82544 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
			    !((unsigned long)(page_to_phys(frag->page) + offset
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
			                      + size - 1) & 4) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
			    size > 4))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
				size -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
			buffer_info->length = size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
			buffer_info->time_stamp = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
			buffer_info->mapped_as_page = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
							offset,	size,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
							DMA_TO_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
				goto dma_error;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
			buffer_info->next_to_watch = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			len -= size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
			offset += size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
			count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	tx_ring->buffer_info[i].skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
	tx_ring->buffer_info[first].next_to_watch = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	return count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
dma_error:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	dev_err(&pdev->dev, "TX DMA map failed\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	if (count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
		count--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	while (count--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		if (i==0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
			i += tx_ring->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		i--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
static void e1000_tx_queue(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			   struct e1000_tx_ring *tx_ring, int tx_flags,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			   int count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	struct e1000_tx_desc *tx_desc = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		             E1000_TXD_CMD_TSE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		txd_lower |= E1000_TXD_CMD_VLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	i = tx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	while (count--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		tx_desc = E1000_TX_DESC(*tx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		tx_desc->lower.data =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			cpu_to_le32(txd_lower | buffer_info->length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		tx_desc->upper.data = cpu_to_le32(txd_upper);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		if (unlikely(++i == tx_ring->count)) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	/* Force memory writes to complete before letting h/w
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	 * know there are new descriptors to fetch.  (Only
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	 * applicable for weak-ordered memory model archs,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	 * such as IA-64). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	wmb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	tx_ring->next_to_use = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	writel(i, hw->hw_addr + tx_ring->tdt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	/* we need this if more than one processor can write to our tail
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	 * at a time, it syncronizes IO on IA64/Altix systems */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	mmiowb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
 * 82547 workaround to avoid controller hang in half-duplex environment.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
 * The workaround is to avoid queuing a large packet that would span
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
 * the internal Tx FIFO ring boundary by notifying the stack to resend
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
 * to the beginning of the Tx FIFO.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
#define E1000_FIFO_HDR			0x10
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
#define E1000_82547_PAD_LEN		0x3E0
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
				       struct sk_buff *skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	if (adapter->link_duplex != HALF_DUPLEX)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		goto no_fifo_stall_required;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	if (atomic_read(&adapter->tx_fifo_stall))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		return 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		atomic_set(&adapter->tx_fifo_stall, 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		return 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
no_fifo_stall_required:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	adapter->tx_fifo_head += skb_fifo_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
2471
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  3110
	if (adapter->ecdev) {
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  3111
		return -EBUSY;
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  3112
	}
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  3113
2386
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	netif_stop_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	/* Herbert's original patch had:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	 *  smp_mb__after_netif_stop_queue();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	 * but since that doesn't exist yet, just open code it. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	smp_mb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	/* We need to check again in a case another CPU has just
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	 * made room available. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		return -EBUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	/* A reprieve! */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	netif_start_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	++adapter->restart_queue;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
static int e1000_maybe_stop_tx(struct net_device *netdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
                               struct e1000_tx_ring *tx_ring, int size)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
		return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	return __e1000_maybe_stop_tx(netdev, size);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
				    struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	struct e1000_tx_ring *tx_ring;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	unsigned int tx_flags = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	unsigned int len = skb_headlen(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	unsigned int nr_frags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	unsigned int mss;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	int count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	int tso;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	unsigned int f;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	/* This goes back to the question of how to logically map a tx queue
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	 * to a flow.  Right now, performance is impacted slightly negatively
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	 * if using multiple tx queues.  If the stack breaks away from a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	 * single qdisc implementation, we can look at this again. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	tx_ring = adapter->tx_ring;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	if (unlikely(skb->len <= 0)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
			dev_kfree_skb_any(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		return NETDEV_TX_OK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	mss = skb_shinfo(skb)->gso_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	/* The controller does a simple calculation to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	 * make sure there is enough room in the FIFO before
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	 * initiating the DMA for each buffer.  The calc is:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	 * 4 = ceil(buffer len/mss).  To make sure we don't
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	 * overrun the FIFO, adjust the max buffer len if mss
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	 * drops. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	if (mss) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
		u8 hdr_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		max_per_txd = min(mss << 2, max_per_txd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
		max_txd_pwr = fls(max_per_txd) - 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
		if (skb->data_len && hdr_len == len) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
			switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
				unsigned int pull_size;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
			case e1000_82544:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
				/* Make sure we have room to chop off 4 bytes,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
				 * and that the end alignment will work out to
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
				 * this hardware's requirements
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
				 * NOTE: this is a TSO only workaround
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
				 * if end byte alignment not correct move us
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
				 * into the next dword */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
				/* fall through */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
				pull_size = min((unsigned int)4, skb->data_len);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
				if (!__pskb_pull_tail(skb, pull_size)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
					e_err(drv, "__pskb_pull_tail "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
					      "failed.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
					dev_kfree_skb_any(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
					return NETDEV_TX_OK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
				len = skb_headlen(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
			default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
				/* do nothing */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	/* reserve a descriptor for the offload context */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
		count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	/* Controller Erratum workaround */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
		count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	count += TXD_USE_COUNT(len, max_txd_pwr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	if (adapter->pcix_82544)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	/* work-around for errata 10 and it applies to all controllers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	 * in PCI-X mode, so add one more descriptor to the count
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
			(len > 2015)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	nr_frags = skb_shinfo(skb)->nr_frags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	for (f = 0; f < nr_frags; f++)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
				       max_txd_pwr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	if (adapter->pcix_82544)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
		count += nr_frags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	/* need: count + 2 desc gap to keep tail from touching
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	 * head, otherwise try next time */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		return NETDEV_TX_BUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	if (unlikely(hw->mac_type == e1000_82547)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
			if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
				netif_stop_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
				if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
					mod_timer(&adapter->tx_fifo_stall_timer,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
					          jiffies + 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
			return NETDEV_TX_BUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	if (unlikely(vlan_tx_tag_present(skb))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
		tx_flags |= E1000_TX_FLAGS_VLAN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	first = tx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	tso = e1000_tso(adapter, tx_ring, skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	if (tso < 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
			dev_kfree_skb_any(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
		return NETDEV_TX_OK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	if (likely(tso)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
		if (likely(hw->mac_type != e1000_82544))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
			tx_ring->last_tx_tso = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
		tx_flags |= E1000_TX_FLAGS_TSO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		tx_flags |= E1000_TX_FLAGS_CSUM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	if (likely(skb->protocol == htons(ETH_P_IP)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
		tx_flags |= E1000_TX_FLAGS_IPV4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	                     nr_frags, mss);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	if (count) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
			/* Make sure there is space in the ring for the next send. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
			e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
			dev_kfree_skb_any(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
		tx_ring->buffer_info[first].time_stamp = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
		tx_ring->next_to_use = first;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	return NETDEV_TX_OK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
 * e1000_tx_timeout - Respond to a Tx Hang
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
static void e1000_tx_timeout(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	/* Do the reset outside of interrupt context */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	adapter->tx_timeout_count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	schedule_work(&adapter->reset_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
static void e1000_reset_task(struct work_struct *work)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	struct e1000_adapter *adapter =
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
		container_of(work, struct e1000_adapter, reset_task);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	e1000_reinit_safe(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
 * e1000_get_stats - Get System Network Statistics
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
 * Returns the address of the device statistics structure.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
 * The statistics are actually updated from the timer callback.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	/* only return the current stats */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	return &netdev->stats;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
 * e1000_change_mtu - Change the Maximum Transfer Unit
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
 * @netdev: network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
 * @new_mtu: new value for maximum frame size
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
 * Returns 0 on success, negative on failure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		return -EBUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		e_err(probe, "Invalid MTU setting\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
		return -EINVAL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
	/* Adapter-specific max frame size limits. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	switch (hw->mac_type) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	case e1000_undefined ... e1000_82542_rev2_1:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
			e_err(probe, "Jumbo Frames not supported.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
			return -EINVAL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		msleep(1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	/* e1000_down has a dependency on max_frame_size */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	hw->max_frame_size = max_frame;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	if (netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	 * means we reserve 2 more, this pushes us to allocate from the next
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	 * larger slab size.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	 * i.e. RXBUFFER_2048 --> size-4096 slab
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	 *  fragmented skbs */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	if (max_frame <= E1000_RXBUFFER_2048)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		adapter->rx_buffer_len = PAGE_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	/* adjust allocation if LPE protects us, and we aren't using SBP */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	if (!hw->tbi_compatibility_on &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	pr_info("%s changing MTU from %d to %d\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
		netdev->name, netdev->mtu, new_mtu);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	netdev->mtu = new_mtu;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	if (netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		e1000_up(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
		e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	clear_bit(__E1000_RESETTING, &adapter->flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
 * e1000_update_stats - Update the board statistics counters
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
void e1000_update_stats(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	unsigned long flags = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	u16 phy_tmp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	 * Prevent stats update while adapter is being reset, or if the pci
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	 * connection is down.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	if (adapter->link_speed == 0)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	if (pci_channel_offline(pdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		spin_lock_irqsave(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	/* these counters are modified from e1000_tbi_adjust_stats,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	 * called from the interrupt context, so they must only
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	 * be written while holding adapter->stats_lock
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	adapter->stats.crcerrs += er32(CRCERRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	adapter->stats.gprc += er32(GPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	adapter->stats.gorcl += er32(GORCL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	adapter->stats.gorch += er32(GORCH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	adapter->stats.bprc += er32(BPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	adapter->stats.mprc += er32(MPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	adapter->stats.roc += er32(ROC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	adapter->stats.prc64 += er32(PRC64);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	adapter->stats.prc127 += er32(PRC127);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	adapter->stats.prc255 += er32(PRC255);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	adapter->stats.prc511 += er32(PRC511);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	adapter->stats.prc1023 += er32(PRC1023);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
	adapter->stats.prc1522 += er32(PRC1522);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	adapter->stats.symerrs += er32(SYMERRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	adapter->stats.mpc += er32(MPC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	adapter->stats.scc += er32(SCC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	adapter->stats.ecol += er32(ECOL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	adapter->stats.mcc += er32(MCC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	adapter->stats.latecol += er32(LATECOL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	adapter->stats.dc += er32(DC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	adapter->stats.sec += er32(SEC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	adapter->stats.rlec += er32(RLEC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	adapter->stats.xonrxc += er32(XONRXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	adapter->stats.xontxc += er32(XONTXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	adapter->stats.xoffrxc += er32(XOFFRXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	adapter->stats.xofftxc += er32(XOFFTXC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	adapter->stats.fcruc += er32(FCRUC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	adapter->stats.gptc += er32(GPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	adapter->stats.gotcl += er32(GOTCL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	adapter->stats.gotch += er32(GOTCH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	adapter->stats.rnbc += er32(RNBC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	adapter->stats.ruc += er32(RUC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	adapter->stats.rfc += er32(RFC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	adapter->stats.rjc += er32(RJC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	adapter->stats.torl += er32(TORL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	adapter->stats.torh += er32(TORH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	adapter->stats.totl += er32(TOTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	adapter->stats.toth += er32(TOTH);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	adapter->stats.tpr += er32(TPR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	adapter->stats.ptc64 += er32(PTC64);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	adapter->stats.ptc127 += er32(PTC127);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	adapter->stats.ptc255 += er32(PTC255);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	adapter->stats.ptc511 += er32(PTC511);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	adapter->stats.ptc1023 += er32(PTC1023);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	adapter->stats.ptc1522 += er32(PTC1522);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	adapter->stats.mptc += er32(MPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	adapter->stats.bptc += er32(BPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	/* used for adaptive IFS */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	hw->tx_packet_delta = er32(TPT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	adapter->stats.tpt += hw->tx_packet_delta;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	hw->collision_delta = er32(COLC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	adapter->stats.colc += hw->collision_delta;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	if (hw->mac_type >= e1000_82543) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		adapter->stats.algnerrc += er32(ALGNERRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		adapter->stats.rxerrc += er32(RXERRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		adapter->stats.tncrs += er32(TNCRS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		adapter->stats.cexterr += er32(CEXTERR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		adapter->stats.tsctc += er32(TSCTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		adapter->stats.tsctfc += er32(TSCTFC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	/* Fill out the OS statistics structure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	netdev->stats.multicast = adapter->stats.mprc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	netdev->stats.collisions = adapter->stats.colc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	/* Rx Errors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	/* RLEC on some newer hardware can be incorrect so build
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	* our own version based on RUC and ROC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	netdev->stats.rx_errors = adapter->stats.rxerrc +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		adapter->stats.crcerrs + adapter->stats.algnerrc +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		adapter->stats.ruc + adapter->stats.roc +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		adapter->stats.cexterr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
	/* Tx Errors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	netdev->stats.tx_errors = adapter->stats.txerrc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
	netdev->stats.tx_window_errors = adapter->stats.latecol;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	if (hw->bad_tx_carr_stats_fd &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	    adapter->link_duplex == FULL_DUPLEX) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		netdev->stats.tx_carrier_errors = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		adapter->stats.tncrs = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	/* Tx Dropped needs to be maintained elsewhere */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	/* Phy Stats */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		if ((adapter->link_speed == SPEED_1000) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
			adapter->phy_stats.idle_errors += phy_tmp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		if ((hw->mac_type <= e1000_82546) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		   (hw->phy_type == e1000_phy_m88) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
			adapter->phy_stats.receive_errors += phy_tmp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* Management Stats */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	if (hw->has_smbus) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		adapter->stats.mgptc += er32(MGTPTC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		adapter->stats.mgprc += er32(MGTPRC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		adapter->stats.mgpdc += er32(MGTPDC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
void ec_poll(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		e1000_watchdog((unsigned long) adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		adapter->ec_watchdog_jiffies = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
	e1000_intr(0, netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
 * e1000_intr - Interrupt Handler
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
 * @irq: interrupt number
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
 * @data: pointer to a network interface device structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
static irqreturn_t e1000_intr(int irq, void *data)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	struct net_device *netdev = data;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	u32 icr = er32(ICR);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	if (unlikely((!icr)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		return IRQ_NONE;  /* Not our interrupt */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	 * we might have caused the interrupt, but the above
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	 * read cleared it, and just in case the driver is
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	 * down there is nothing to do so return handled
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		return IRQ_HANDLED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		hw->get_link_status = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		/* guard against interrupt when we're going down */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		int i, ec_work_done = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		for (i = 0; i < E1000_MAX_INTR; i++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
							&ec_work_done, 100) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		/* disable interrupts, without the synchronize_irq bit */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
		ew32(IMC, ~0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		E1000_WRITE_FLUSH();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
		if (likely(napi_schedule_prep(&adapter->napi))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
			adapter->total_tx_bytes = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
			adapter->total_tx_packets = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
			adapter->total_rx_bytes = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
			adapter->total_rx_packets = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
			__napi_schedule(&adapter->napi);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
			/* this really should not happen! if it does it is basically a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
			 * bug, but not a hard error, so enable ints and continue */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
			if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
				e1000_irq_enable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	return IRQ_HANDLED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
 * e1000_clean - NAPI Rx polling callback
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
 * EtherCAT: never called
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
static int e1000_clean(struct napi_struct *napi, int budget)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	int tx_clean_complete = 0, work_done = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	if (!tx_clean_complete)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		work_done = budget;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	/* If budget not fully consumed, exit the polling mode */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	if (work_done < budget) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		if (likely(adapter->itr_setting & 3))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
			e1000_set_itr(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		napi_complete(napi);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
			e1000_irq_enable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	return work_done;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
			       struct e1000_tx_ring *tx_ring)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	struct e1000_tx_desc *tx_desc, *eop_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	unsigned int i, eop;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	unsigned int count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	unsigned int total_tx_bytes=0, total_tx_packets=0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	i = tx_ring->next_to_clean;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	eop = tx_ring->buffer_info[i].next_to_watch;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	       (count < tx_ring->count)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
		bool cleaned = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		rmb();	/* read buffer_info after eop_desc */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
		for ( ; !cleaned; count++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			tx_desc = E1000_TX_DESC(*tx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
			buffer_info = &tx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
			cleaned = (i == eop);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
			if (cleaned) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
				struct sk_buff *skb = buffer_info->skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
				unsigned int segs, bytecount;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
				segs = skb_shinfo(skb)->gso_segs ?: 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
				/* multiply data chunks by size of headers */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
				bytecount = ((segs - 1) * skb_headlen(skb)) +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
				            skb->len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
				total_tx_packets += segs;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
				total_tx_bytes += bytecount;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
			tx_desc->upper.data = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
			if (unlikely(++i == tx_ring->count)) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
		eop = tx_ring->buffer_info[i].next_to_watch;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	tx_ring->next_to_clean = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
#define TX_WAKE_THRESHOLD 32
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		/* Make sure that anybody stopping the queue after this
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		 * sees the new next_to_clean.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		smp_mb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		if (netif_queue_stopped(netdev) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
			netif_wake_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
			++adapter->restart_queue;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	if (!adapter->ecdev && adapter->detect_tx_hung) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		/* Detect a transmit hang in hardware, this serializes the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		 * check with the clearing of time_stamp and movement of i */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		adapter->detect_tx_hung = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		if (tx_ring->buffer_info[eop].time_stamp &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		               (adapter->tx_timeout_factor * HZ)) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
			/* detected Tx unit hang */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
			e_err(drv, "Detected Tx Unit Hang\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
			      "  Tx Queue             <%lu>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
			      "  TDH                  <%x>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
			      "  TDT                  <%x>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
			      "  next_to_use          <%x>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
			      "  next_to_clean        <%x>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
			      "buffer_info[next_to_clean]\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
			      "  time_stamp           <%lx>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			      "  next_to_watch        <%x>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
			      "  jiffies              <%lx>\n"
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
			      "  next_to_watch.status <%x>\n",
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
				(unsigned long)((tx_ring - adapter->tx_ring) /
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
					sizeof(struct e1000_tx_ring)),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
				readl(hw->hw_addr + tx_ring->tdh),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
				readl(hw->hw_addr + tx_ring->tdt),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
				tx_ring->next_to_use,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
				tx_ring->next_to_clean,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
				tx_ring->buffer_info[eop].time_stamp,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
				eop,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
				jiffies,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
				eop_desc->upper.fields.status);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
			netif_stop_queue(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	adapter->total_tx_bytes += total_tx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	adapter->total_tx_packets += total_tx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	netdev->stats.tx_bytes += total_tx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	netdev->stats.tx_packets += total_tx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	return count < tx_ring->count;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
 * e1000_rx_checksum - Receive Checksum Offload for 82543
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
 * @adapter:     board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
 * @status_err:  receive descriptor status and error fields
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
 * @csum:        receive descriptor csum field
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
 * @sk_buff:     socket buffer with received data
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
			      u32 csum, struct sk_buff *skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	u16 status = (u16)status_err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	u8 errors = (u8)(status_err >> 24);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	skb_checksum_none_assert(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	/* 82543 or newer only */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	if (unlikely(hw->mac_type < e1000_82543)) return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	/* Ignore Checksum bit is set */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	/* TCP/UDP checksum error bit is set */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		/* let the stack verify checksum errors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		adapter->hw_csum_err++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	/* TCP/UDP Checksum has not been calculated */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	if (!(status & E1000_RXD_STAT_TCPCS))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
	/* It must be a TCP or UDP packet with a valid checksum */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		/* TCP checksum is good */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		skb->ip_summed = CHECKSUM_UNNECESSARY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	adapter->hw_csum_good++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 * e1000_consume_page - helper function
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
                               u16 length)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	bi->page = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	skb->len += length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	skb->data_len += length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	skb->truesize += length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
 * e1000_receive_skb - helper function to handle rx indications
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
 * @status: descriptor status field as written by hardware
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
 * @skb: pointer to sk_buff to be indicated to stack
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
			      __le16 vlan, struct sk_buff *skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	skb->protocol = eth_type_trans(skb, adapter->netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
				 le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
				 skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		napi_gro_receive(&adapter->napi, skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
 * @rx_ring: ring to clean
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
 * @work_done: amount of napi work completed this call
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
 * @work_to_do: max amount of work allowed for this call to do
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
 * the return value indicates whether actual cleaning was done, there
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
 * is no guarantee that everything was cleaned
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
				     struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
				     int *work_done, int work_to_do)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	struct e1000_rx_desc *rx_desc, *next_rxd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	struct e1000_buffer *buffer_info, *next_buffer;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	unsigned long irq_flags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	u32 length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	int cleaned_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	bool cleaned = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
	unsigned int total_rx_bytes=0, total_rx_packets=0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	i = rx_ring->next_to_clean;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
	rx_desc = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	while (rx_desc->status & E1000_RXD_STAT_DD) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
		struct sk_buff *skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
		u8 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		if (*work_done >= work_to_do)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		(*work_done)++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
		rmb(); /* read descriptor and rx_buffer_info after status DD */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		status = rx_desc->status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
		skb = buffer_info->skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
		if (++i == rx_ring->count) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
		next_rxd = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
		prefetch(next_rxd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		next_buffer = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		cleaned = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		cleaned_count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		dma_unmap_page(&pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
			       buffer_info->length, DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		length = le16_to_cpu(rx_desc->length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		/* errors is only valid for DD + EOP descriptors */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		if (!adapter->ecdev &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		    unlikely((status & E1000_RXD_STAT_EOP) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
			u8 last_byte = *(skb->data + length - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
				       last_byte)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
				spin_lock_irqsave(&adapter->stats_lock,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
				                  irq_flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
				e1000_tbi_adjust_stats(hw, &adapter->stats,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
				                       length, skb->data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
				spin_unlock_irqrestore(&adapter->stats_lock,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
				                       irq_flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
				length--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
				/* recycle both page and skb */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
				buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
				/* an error means any chain goes out the window
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
				 * too */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
				if (rx_ring->rx_skb_top)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
					dev_kfree_skb(rx_ring->rx_skb_top);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
				rx_ring->rx_skb_top = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
				goto next_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
#define rxtop rx_ring->rx_skb_top
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		if (!(status & E1000_RXD_STAT_EOP)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
			/* this descriptor is only the beginning (or middle) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
			if (!rxtop) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
				/* this is the beginning of a chain */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
				rxtop = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
				                   0, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
				/* this is the middle of a chain */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
				skb_fill_page_desc(rxtop,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
				    skb_shinfo(rxtop)->nr_frags,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
				    buffer_info->page, 0, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
				/* re-use the skb, only consumed the page */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
				buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
			e1000_consume_page(buffer_info, rxtop, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			goto next_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			if (rxtop) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
				/* end of the chain */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
				skb_fill_page_desc(rxtop,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
				    skb_shinfo(rxtop)->nr_frags,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
				    buffer_info->page, 0, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
				/* re-use the current skb, we only consumed the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
				 * page */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
				buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
				skb = rxtop;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
				rxtop = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
				e1000_consume_page(buffer_info, skb, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
				/* no chain, got EOP, this buf is the packet
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
				 * copybreak to save the put_page/alloc_page */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
				if (length <= copybreak &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
				    skb_tailroom(skb) >= length) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
					u8 *vaddr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
					vaddr = kmap_atomic(buffer_info->page,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
					                    KM_SKB_DATA_SOFTIRQ);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
					memcpy(skb_tail_pointer(skb), vaddr, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
					kunmap_atomic(vaddr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
					              KM_SKB_DATA_SOFTIRQ);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
					/* re-use the page, so don't erase
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
					 * buffer_info->page */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
					skb_put(skb, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
				} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
					skb_fill_page_desc(skb, 0,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
					                   buffer_info->page, 0,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
				                           length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
					e1000_consume_page(buffer_info, skb,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
					                   length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		e1000_rx_checksum(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
		                  (u32)(status) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		                  ((u32)(rx_desc->errors) << 24),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		                  le16_to_cpu(rx_desc->csum), skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		pskb_trim(skb, skb->len - 4);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		/* probably a little skewed due to removing CRC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
		total_rx_bytes += skb->len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		total_rx_packets++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
		/* eth type trans needs skb->data to point to something */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
		if (!pskb_may_pull(skb, ETH_HLEN)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
			e_err(drv, "pskb_may_pull failed.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
				dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
			goto next_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
			ecdev_receive(adapter->ecdev, skb->data, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
			// No need to detect link status as
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
			// long as frames are received: Reset watchdog.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
			adapter->ec_watchdog_jiffies = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
next_desc:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		rx_desc->status = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		/* return some buffers to hardware, one at a time is too slow */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
			cleaned_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
		/* use prefetched values */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
		rx_desc = next_rxd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
		buffer_info = next_buffer;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	rx_ring->next_to_clean = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	if (cleaned_count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	adapter->total_rx_packets += total_rx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
	adapter->total_rx_bytes += total_rx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	netdev->stats.rx_bytes += total_rx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
	netdev->stats.rx_packets += total_rx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	return cleaned;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
 * this should improve performance for small packets with large amounts
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
 * of reassembly being done in the stack
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
static void e1000_check_copybreak(struct net_device *netdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
				 struct e1000_buffer *buffer_info,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
				 u32 length, struct sk_buff **skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	struct sk_buff *new_skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	if (adapter->ecdev || length > copybreak)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	if (!new_skb)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
				       (*skb)->data - NET_IP_ALIGN,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
				       length + NET_IP_ALIGN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	/* save the skb in buffer_info as good */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	buffer_info->skb = *skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	*skb = new_skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
 * @adapter: board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
 * @rx_ring: ring to clean
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
 * @work_done: amount of napi work completed this call
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
 * @work_to_do: max amount of work allowed for this call to do
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
			       struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
			       int *work_done, int work_to_do)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	struct e1000_rx_desc *rx_desc, *next_rxd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	struct e1000_buffer *buffer_info, *next_buffer;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	unsigned long flags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	u32 length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	int cleaned_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	bool cleaned = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	unsigned int total_rx_bytes=0, total_rx_packets=0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	i = rx_ring->next_to_clean;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	rx_desc = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	while (rx_desc->status & E1000_RXD_STAT_DD) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		struct sk_buff *skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		u8 status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		if (*work_done >= work_to_do)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
		(*work_done)++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		rmb(); /* read descriptor and rx_buffer_info after status DD */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		status = rx_desc->status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
		skb = buffer_info->skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
			buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		prefetch(skb->data - NET_IP_ALIGN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		if (++i == rx_ring->count) i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
		next_rxd = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		prefetch(next_rxd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		next_buffer = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		cleaned = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
		cleaned_count++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		dma_unmap_single(&pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
				 buffer_info->length, DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
		buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		length = le16_to_cpu(rx_desc->length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
		/* !EOP means multiple descriptors were used to store a single
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		 * packet, if thats the case we need to toss it.  In fact, we
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		 * to toss every packet with the EOP bit clear and the next
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		 * frame that _does_ have the EOP bit set, as it is by
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		 * definition only a frame fragment
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
			adapter->discarding = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		if (adapter->discarding) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
			/* All receives must fit into a single buffer */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
			e_dbg("Receive packet consumed multiple buffers\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
			/* recycle */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
			buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			if (status & E1000_RXD_STAT_EOP)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
				adapter->discarding = false;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
			goto next_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
		if (!adapter->ecdev &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
		    unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			u8 last_byte = *(skb->data + length - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
				       last_byte)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
				spin_lock_irqsave(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
				e1000_tbi_adjust_stats(hw, &adapter->stats,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
				                       length, skb->data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
				spin_unlock_irqrestore(&adapter->stats_lock,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
				                       flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
				length--;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
				/* recycle */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
				buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
				goto next_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		/* adjust length to remove Ethernet CRC, this must be
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		 * done after the TBI_ACCEPT workaround above */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		length -= 4;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		/* probably a little skewed due to removing CRC */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		total_rx_bytes += length;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		total_rx_packets++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		skb_put(skb, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
		/* Receive Checksum Offload */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
		e1000_rx_checksum(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
				  (u32)(status) |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
				  ((u32)(rx_desc->errors) << 24),
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
				  le16_to_cpu(rx_desc->csum), skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
			ecdev_receive(adapter->ecdev, skb->data, length);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			// No need to detect link status as
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
			// long as frames are received: Reset watchdog.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
			adapter->ec_watchdog_jiffies = jiffies;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
next_desc:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		rx_desc->status = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		/* return some buffers to hardware, one at a time is too slow */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
			cleaned_count = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		/* use prefetched values */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
		rx_desc = next_rxd;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		buffer_info = next_buffer;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	rx_ring->next_to_clean = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	if (cleaned_count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	adapter->total_rx_packets += total_rx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	adapter->total_rx_bytes += total_rx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	netdev->stats.rx_bytes += total_rx_bytes;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	netdev->stats.rx_packets += total_rx_packets;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	return cleaned;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
 * @adapter: address of board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
 * @rx_ring: pointer to receive ring structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
 * @cleaned_count: number of buffers to allocate this pass
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
static void
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	struct e1000_rx_desc *rx_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
	struct sk_buff *skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
	i = rx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	while (cleaned_count--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		skb = buffer_info->skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		if (skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
			skb_trim(skb, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
			goto check_page;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		if (unlikely(!skb)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
			/* Better luck next round */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
			adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		/* Fix for errata 23, can't cross 64kB boundary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
			struct sk_buff *oldskb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
			e_err(rx_err, "skb align check failed: %u bytes at "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
			      "%p\n", bufsz, skb->data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
			/* Try again, without freeing the previous */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			/* Failed allocation, critical failure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
			if (!skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
				dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
				adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
				/* give up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
				dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
				dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
				break; /* while (cleaned_count--) */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
			/* Use new allocation */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
			dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		buffer_info->length = adapter->rx_buffer_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
check_page:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		/* allocate a new page if necessary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		if (!buffer_info->page) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
			buffer_info->page = alloc_page(GFP_ATOMIC);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
			if (unlikely(!buffer_info->page)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
				adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		if (!buffer_info->dma) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			buffer_info->dma = dma_map_page(&pdev->dev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
			                                buffer_info->page, 0,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
							buffer_info->length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
							DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
				put_page(buffer_info->page);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
				dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
				buffer_info->page = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
				buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
				buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
				adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
				break; /* while !buffer_info->skb */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		rx_desc = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		if (unlikely(++i == rx_ring->count))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
			i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	if (likely(rx_ring->next_to_use != i)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
		rx_ring->next_to_use = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		if (unlikely(i-- == 0))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
			i = (rx_ring->count - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
		/* Force memory writes to complete before letting h/w
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		 * know there are new descriptors to fetch.  (Only
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
		 * applicable for weak-ordered memory model archs,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		 * such as IA-64). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
		wmb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
 * @adapter: address of board private structure
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
				   struct e1000_rx_ring *rx_ring,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
				   int cleaned_count)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
	struct net_device *netdev = adapter->netdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	struct pci_dev *pdev = adapter->pdev;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	struct e1000_rx_desc *rx_desc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	struct e1000_buffer *buffer_info;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	struct sk_buff *skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	unsigned int i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	unsigned int bufsz = adapter->rx_buffer_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	i = rx_ring->next_to_use;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	while (cleaned_count--) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		skb = buffer_info->skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		if (skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
			skb_trim(skb, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
			goto map_skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		if (unlikely(!skb)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
			/* Better luck next round */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
			adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
			break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		/* Fix for errata 23, can't cross 64kB boundary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
			struct sk_buff *oldskb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
			e_err(rx_err, "skb align check failed: %u bytes at "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
			      "%p\n", bufsz, skb->data);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
			/* Try again, without freeing the previous */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
			/* Failed allocation, critical failure */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
			if (!skb) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
				dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
				adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
				/* give up */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
				dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
				dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
				adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
				break; /* while !buffer_info->skb */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			/* Use new allocation */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			dev_kfree_skb(oldskb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
		buffer_info->skb = skb;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		buffer_info->length = adapter->rx_buffer_len;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
map_skb:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
		buffer_info->dma = dma_map_single(&pdev->dev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
						  skb->data,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
						  buffer_info->length,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
						  DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
			dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
			buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
			buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
			adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
			break; /* while !buffer_info->skb */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
		 * XXX if it was allocated cleanly it will never map to a
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		 * boundary crossing
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
		/* Fix for errata 23, can't cross 64kB boundary */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		if (!e1000_check_64k_bound(adapter,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
					(void *)(unsigned long)buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
					adapter->rx_buffer_len)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
			e_err(rx_err, "dma align check failed: %u bytes at "
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
			      "%p\n", adapter->rx_buffer_len,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
			      (void *)(unsigned long)buffer_info->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
			dev_kfree_skb(skb);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
			buffer_info->skb = NULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
			dma_unmap_single(&pdev->dev, buffer_info->dma,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
					 adapter->rx_buffer_len,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
					 DMA_FROM_DEVICE);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
			buffer_info->dma = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
			adapter->alloc_rx_buff_failed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
			break; /* while !buffer_info->skb */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		rx_desc = E1000_RX_DESC(*rx_ring, i);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
		if (unlikely(++i == rx_ring->count))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
			i = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		buffer_info = &rx_ring->buffer_info[i];
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
	if (likely(rx_ring->next_to_use != i)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
		rx_ring->next_to_use = i;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		if (unlikely(i-- == 0))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
			i = (rx_ring->count - 1);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		/* Force memory writes to complete before letting h/w
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		 * know there are new descriptors to fetch.  (Only
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
		 * applicable for weak-ordered memory model archs,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		 * such as IA-64). */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		wmb();
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		writel(i, hw->hw_addr + rx_ring->rdt);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
 * @adapter:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
static void e1000_smartspeed(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	u16 phy_status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	u16 phy_ctrl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	if (adapter->smartspeed == 0) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		/* If Master/Slave config fault is asserted twice,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		 * we assume back-to-back */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
					    phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
			adapter->smartspeed++;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
			if (!e1000_phy_setup_autoneg(hw) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
			   !e1000_read_phy_reg(hw, PHY_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
				   	       &phy_ctrl)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
					     MII_CR_RESTART_AUTO_NEG);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
				e1000_write_phy_reg(hw, PHY_CTRL,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
						    phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		/* If still no link, perhaps using 2/3 pair cable */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
		phy_ctrl |= CR_1000T_MS_ENABLE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		if (!e1000_phy_setup_autoneg(hw) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
				     MII_CR_RESTART_AUTO_NEG);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		adapter->smartspeed = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
 * e1000_ioctl -
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
 * @netdev:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
 * @ifreq:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
 * @cmd:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	switch (cmd) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	case SIOCGMIIPHY:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	case SIOCGMIIREG:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	case SIOCSMIIREG:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
		return e1000_mii_ioctl(netdev, ifr, cmd);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		return -EOPNOTSUPP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
 * e1000_mii_ioctl -
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
 * @netdev:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
 * @ifreq:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
 * @cmd:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
 **/
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
			   int cmd)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	struct mii_ioctl_data *data = if_mii(ifr);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	int retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	u16 mii_reg;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	unsigned long flags;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	if (hw->media_type != e1000_media_type_copper)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
		return -EOPNOTSUPP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	switch (cmd) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	case SIOCGMIIPHY:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		data->phy_id = hw->phy_addr;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	case SIOCGMIIREG:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			return -EPERM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
		spin_lock_irqsave(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
				   &data->val_out)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			return -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	case SIOCSMIIREG:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			return -EPERM;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		if (data->reg_num & ~(0x1F))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
			return -EFAULT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		mii_reg = data->val_in;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
		spin_lock_irqsave(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		if (e1000_write_phy_reg(hw, data->reg_num,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
					mii_reg)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
			return -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		if (hw->media_type == e1000_media_type_copper) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			switch (data->reg_num) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
			case PHY_CTRL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
				if (mii_reg & MII_CR_POWER_DOWN)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
					hw->autoneg = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
					hw->autoneg_advertised = 0x2F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
				} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
					u32 speed;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
					if (mii_reg & 0x40)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
						speed = SPEED_1000;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
					else if (mii_reg & 0x2000)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
						speed = SPEED_100;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
					else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
						speed = SPEED_10;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
					retval = e1000_set_spd_dplx(
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
						adapter, speed,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
						((mii_reg & 0x100)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
						 ? DUPLEX_FULL :
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
						 DUPLEX_HALF));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
					if (retval)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
						return retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
				}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
				if (netif_running(adapter->netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
					e1000_reinit_locked(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
				else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
					e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
			case M88E1000_PHY_SPEC_CTRL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
			case M88E1000_EXT_PHY_SPEC_CTRL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
				if (e1000_phy_reset(hw))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
					return -EIO;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
			switch (data->reg_num) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
			case PHY_CTRL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
				if (mii_reg & MII_CR_POWER_DOWN)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
					break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
				if (netif_running(adapter->netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
					e1000_reinit_locked(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
				else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
					e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
				break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
			}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		return -EOPNOTSUPP;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	return E1000_SUCCESS;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
void e1000_pci_set_mwi(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	struct e1000_adapter *adapter = hw->back;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	int ret_val = pci_set_mwi(adapter->pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	if (ret_val)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
		e_err(probe, "Error in setting MWI\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
void e1000_pci_clear_mwi(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	struct e1000_adapter *adapter = hw->back;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	pci_clear_mwi(adapter->pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	struct e1000_adapter *adapter = hw->back;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	return pcix_get_mmrbc(adapter->pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	struct e1000_adapter *adapter = hw->back;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	pcix_set_mmrbc(adapter->pdev, mmrbc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
	outl(value, port);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
static void e1000_vlan_rx_register(struct net_device *netdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
				   struct vlan_group *grp)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	u32 ctrl, rctl;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		e1000_irq_disable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	adapter->vlgrp = grp;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	if (grp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		/* enable VLAN tag insert/strip */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		ctrl |= E1000_CTRL_VME;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
		/* enable VLAN receive filtering */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		rctl &= ~E1000_RCTL_CFIEN;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
		if (!(netdev->flags & IFF_PROMISC))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
			rctl |= E1000_RCTL_VFE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
		ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
		e1000_update_mng_vlan(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
		/* disable VLAN tag insert/strip */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
		ctrl &= ~E1000_CTRL_VME;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
		/* disable VLAN receive filtering */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
		rctl &= ~E1000_RCTL_VFE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
		e1000_irq_enable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	u32 vfta, index;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	if ((hw->mng_cookie.status &
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	    (vid == adapter->mng_vlan_id))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	/* add VID to filter table */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	index = (vid >> 5) & 0x7F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	vfta |= (1 << (vid & 0x1F));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	e1000_write_vfta(hw, index, vfta);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	u32 vfta, index;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		e1000_irq_disable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	if (!test_bit(__E1000_DOWN, &adapter->flags))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
		e1000_irq_enable(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	/* remove VID from filter table */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	index = (vid >> 5) & 0x7F;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	vfta &= ~(1 << (vid & 0x1F));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	e1000_write_vfta(hw, index, vfta);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
static void e1000_restore_vlan(struct e1000_adapter *adapter)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	if (adapter->vlgrp) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		u16 vid;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		for (vid = 0; vid < VLAN_N_VID; vid++) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
			if (!vlan_group_get_device(adapter->vlgrp, vid))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
				continue;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	hw->autoneg = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	/* Make sure dplx is at most 1 bit and lsb of speed is not set
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	 * for the switch() below to work */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	if ((spd & 1) || (dplx & ~1))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		goto err_inval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	/* Fiber NICs only allow 1000 gbps Full duplex */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	if ((hw->media_type == e1000_media_type_fiber) &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	    spd != SPEED_1000 &&
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	    dplx != DUPLEX_FULL)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		goto err_inval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	switch (spd + dplx) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	case SPEED_10 + DUPLEX_HALF:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
		hw->forced_speed_duplex = e1000_10_half;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	case SPEED_10 + DUPLEX_FULL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		hw->forced_speed_duplex = e1000_10_full;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	case SPEED_100 + DUPLEX_HALF:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
		hw->forced_speed_duplex = e1000_100_half;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	case SPEED_100 + DUPLEX_FULL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		hw->forced_speed_duplex = e1000_100_full;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	case SPEED_1000 + DUPLEX_FULL:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
		hw->autoneg = 1;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		break;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
	default:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
		goto err_inval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
err_inval:
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	e_err(probe, "Unsupported Speed/Duplex configuration\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	return -EINVAL;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	u32 ctrl, ctrl_ext, rctl, status;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	u32 wufc = adapter->wol;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
#ifdef CONFIG_PM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	int retval = 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
		return -EBUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	netif_device_detach(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
	if (netif_running(netdev)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
#ifdef CONFIG_PM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	retval = pci_save_state(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
	if (retval)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		return retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
	status = er32(STATUS);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	if (status & E1000_STATUS_LU)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		wufc &= ~E1000_WUFC_LNKC;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	if (wufc) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		e1000_setup_rctl(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		e1000_set_rx_mode(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
		/* turn on all-multi mode if wake on multicast is enabled */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
		if (wufc & E1000_WUFC_MC) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
			rctl = er32(RCTL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
			rctl |= E1000_RCTL_MPE;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
			ew32(RCTL, rctl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
		if (hw->mac_type >= e1000_82540) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
			ctrl = er32(CTRL);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
			/* advertise wake from D3Cold */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
			#define E1000_CTRL_ADVD3WUC 0x00100000
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
			/* phy power management enable */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
			ctrl |= E1000_CTRL_ADVD3WUC |
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
				E1000_CTRL_EN_PHY_PWR_MGMT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
			ew32(CTRL, ctrl);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		if (hw->media_type == e1000_media_type_fiber ||
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		    hw->media_type == e1000_media_type_internal_serdes) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
			/* keep the laser running in D3 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			ctrl_ext = er32(CTRL_EXT);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
			ew32(CTRL_EXT, ctrl_ext);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		ew32(WUC, E1000_WUC_PME_EN);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
		ew32(WUFC, wufc);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
		ew32(WUC, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
		ew32(WUFC, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	e1000_release_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	*enable_wake = !!wufc;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
	/* make sure adapter isn't asleep if manageability is enabled */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
	if (adapter->en_mng_pt)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		*enable_wake = true;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	if (netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
		e1000_free_irq(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
	pci_disable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
#ifdef CONFIG_PM
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	int retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	bool wake;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	retval = __e1000_shutdown(pdev, &wake);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	if (retval)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
		return retval;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	if (wake) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
		pci_prepare_to_sleep(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	} else {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
		pci_wake_from_d3(pdev, false);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
		pci_set_power_state(pdev, PCI_D3hot);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
static int e1000_resume(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	u32 err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	if (adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
		return -EBUSY;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
	pci_set_power_state(pdev, PCI_D0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
	pci_restore_state(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	pci_save_state(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	if (adapter->need_ioport)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
		err = pci_enable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
		err = pci_enable_device_mem(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
		pr_err("Cannot enable PCI device from suspend\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	pci_set_master(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	pci_enable_wake(pdev, PCI_D3hot, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	pci_enable_wake(pdev, PCI_D3cold, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	if (netif_running(netdev)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		err = e1000_request_irq(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
		if (err)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
			return err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
	e1000_power_up_phy(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
	e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	ew32(WUS, ~0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	e1000_init_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
	if (netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
		e1000_up(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	if (!adapter->ecdev) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		netif_device_attach(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	return 0;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
static void e1000_shutdown(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	bool wake;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
	__e1000_shutdown(pdev, &wake);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	if (system_state == SYSTEM_POWER_OFF) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
		pci_wake_from_d3(pdev, wake);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
		pci_set_power_state(pdev, PCI_D3hot);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
#ifdef CONFIG_NET_POLL_CONTROLLER
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
/*
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
 * Polling 'interrupt' - used by things like netconsole to send skbs
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
 * without having to re-enable interrupts. It's not called while
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
 * the interrupt routine is executing.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
static void e1000_netpoll(struct net_device *netdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	disable_irq(adapter->pdev->irq);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	e1000_intr(adapter->pdev->irq, netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	enable_irq(adapter->pdev->irq);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
#endif
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
 * e1000_io_error_detected - called when PCI error is detected
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
 * @pdev: Pointer to PCI device
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
 * @state: The current pci connection state
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
 * This function is called after a PCI bus error affecting
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
 * this device has been detected.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
						pci_channel_state_t state)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	netif_device_detach(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	if (state == pci_channel_io_perm_failure)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		return PCI_ERS_RESULT_DISCONNECT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	if (netif_running(netdev))
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
		e1000_down(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	pci_disable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
	/* Request a slot slot reset. */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	return PCI_ERS_RESULT_NEED_RESET;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
 * e1000_io_slot_reset - called after the pci bus has been reset.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
 * @pdev: Pointer to PCI device
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
 * Restart the card from scratch, as if from a cold-boot. Implementation
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
 * resembles the first-half of the e1000_resume routine.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	struct e1000_hw *hw = &adapter->hw;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
	int err;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	if (adapter->need_ioport)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		err = pci_enable_device(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	else
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
		err = pci_enable_device_mem(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	if (err) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		pr_err("Cannot re-enable PCI device after reset.\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		return PCI_ERS_RESULT_DISCONNECT;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	pci_set_master(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
	pci_enable_wake(pdev, PCI_D3hot, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	pci_enable_wake(pdev, PCI_D3cold, 0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	e1000_reset(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	ew32(WUS, ~0);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	return PCI_ERS_RESULT_RECOVERED;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
/**
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
 * e1000_io_resume - called when traffic can start flowing again.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
 * @pdev: Pointer to PCI device
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
 *
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
 * This callback is called when the error recovery driver tells us that
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
 * its OK to resume normal operation. Implementation resembles the
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
 * second-half of the e1000_resume routine.
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
 */
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
static void e1000_io_resume(struct pci_dev *pdev)
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
{
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
	struct net_device *netdev = pci_get_drvdata(pdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
	struct e1000_adapter *adapter = netdev_priv(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
	e1000_init_manageability(adapter);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
	if (netif_running(netdev)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
		if (e1000_up(adapter)) {
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
			pr_info("can't bring device back up after reset\n");
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
			return;
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
	}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	netif_device_attach(netdev);
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
}
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
6742f8751872 Added e1000 driver for kernel 3.0.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
/* e1000_main.c */