devices/e1000/e1000_main-2.6.35-orig.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2282 9c0710c38627
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k6-NAPI"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
				    struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static int e1000_set_mac(struct net_device *netdev, void *p);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr(int irq, void *data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
				     struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
				     int *work_done, int work_to_do);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
				   struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				   int cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
					 struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
					 int cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			   int cmd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_tx_timeout(struct net_device *dev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_reset_task(struct work_struct *work);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_smartspeed(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
                                       struct sk_buff *skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_restore_vlan(struct e1000_adapter *adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_PM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static int e1000_resume(struct pci_dev *pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_shutdown(struct pci_dev *pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
#ifdef CONFIG_NET_POLL_CONTROLLER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
/* for netdump / net console */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_netpoll (struct net_device *netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
#define COPYBREAK_DEFAULT 256
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
module_param(copybreak, uint, 0644);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
MODULE_PARM_DESC(copybreak,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	"Maximum size of packet that is copied to a new buffer on receive");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
                     pci_channel_state_t state);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_io_resume(struct pci_dev *pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static struct pci_error_handlers e1000_err_handler = {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	.error_detected = e1000_io_error_detected,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	.slot_reset = e1000_io_slot_reset,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.resume = e1000_io_resume,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
static struct pci_driver e1000_driver = {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.name     = e1000_driver_name,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	.id_table = e1000_pci_tbl,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	.probe    = e1000_probe,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.remove   = __devexit_p(e1000_remove),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
#ifdef CONFIG_PM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	/* Power Managment Hooks */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.suspend  = e1000_suspend,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.resume   = e1000_resume,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	.shutdown = e1000_shutdown,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.err_handler = &e1000_err_handler
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
MODULE_LICENSE("GPL");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
MODULE_VERSION(DRV_VERSION);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
module_param(debug, int, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 * e1000_get_hw_dev - return device
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
 * used by hardware layer to print debugging information
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	struct e1000_adapter *adapter = hw->back;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	return adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
 * e1000_init_module - Driver Registration Routine
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
 * e1000_init_module is the first routine called when the driver is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
 * loaded. All it does is register with the PCI subsystem.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
static int __init e1000_init_module(void)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	int ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	pr_info("%s\n", e1000_copyright);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	ret = pci_register_driver(&e1000_driver);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	if (copybreak != COPYBREAK_DEFAULT) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		if (copybreak == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
			pr_info("copybreak disabled\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
			pr_info("copybreak enabled for "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
				   "packets <= %u bytes\n", copybreak);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	return ret;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
module_init(e1000_init_module);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
 * e1000_exit_module - Driver Exit Cleanup Routine
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 * e1000_exit_module is called just before the driver is removed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 * from memory.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
static void __exit e1000_exit_module(void)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	pci_unregister_driver(&e1000_driver);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
module_exit(e1000_exit_module);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
static int e1000_request_irq(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	irq_handler_t handler = e1000_intr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	int irq_flags = IRQF_SHARED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	int err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	                  netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		e_err("Unable to allocate interrupt Error: %d\n", err);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
static void e1000_free_irq(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	free_irq(adapter->pdev->irq, netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
 * e1000_irq_disable - Mask off interrupt generation on the NIC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
static void e1000_irq_disable(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	ew32(IMC, ~0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	synchronize_irq(adapter->pdev->irq);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 * e1000_irq_enable - Enable default interrupt generation settings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
static void e1000_irq_enable(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	ew32(IMS, IMS_ENABLE_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	u16 vid = hw->mng_cookie.vlan_id;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	u16 old_vid = adapter->mng_vlan_id;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	if (adapter->vlgrp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
			if (hw->mng_cookie.status &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
				e1000_vlan_rx_add_vid(netdev, vid);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
				adapter->mng_vlan_id = vid;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
			} else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
					(vid != old_vid) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
				e1000_vlan_rx_kill_vid(netdev, old_vid);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		} else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
			adapter->mng_vlan_id = vid;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
static void e1000_init_manageability(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	if (adapter->en_mng_pt) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		u32 manc = er32(MANC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		/* disable hardware interception of ARP */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		manc &= ~(E1000_MANC_ARP_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		ew32(MANC, manc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
static void e1000_release_manageability(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	if (adapter->en_mng_pt) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		u32 manc = er32(MANC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		/* re-enable hardware interception of ARP */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		manc |= E1000_MANC_ARP_EN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		ew32(MANC, manc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
 * e1000_configure - configure the hardware for RX and TX
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
 * @adapter = private board structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
static void e1000_configure(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	e1000_set_rx_mode(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	e1000_restore_vlan(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	e1000_init_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	e1000_configure_tx(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	e1000_setup_rctl(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	e1000_configure_rx(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	/* call E1000_DESC_UNUSED which always leaves
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	 * at least 1 descriptor unused to make sure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	 * next_to_use != next_to_clean */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	for (i = 0; i < adapter->num_rx_queues; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		adapter->alloc_rx_buf(adapter, ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		                      E1000_DESC_UNUSED(ring));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
int e1000_up(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	/* hardware has been reset, we need to reload some things */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	e1000_configure(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
	clear_bit(__E1000_DOWN, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	napi_enable(&adapter->napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	netif_wake_queue(adapter->netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	/* fire a link change interrupt to start the watchdog */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	ew32(ICS, E1000_ICS_LSC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
 * e1000_power_up_phy - restore link in case the phy was powered down
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
 * @adapter: address of board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 * The phy may be powered down to save power and turn off link when the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
 * driver is unloaded and wake on lan is not enabled (among others)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
 * *** this routine MUST be followed by a call to e1000_reset ***
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
void e1000_power_up_phy(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	u16 mii_reg = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	/* Just clear the power down bit to wake the phy back up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		/* according to the manual, the phy will retain its
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		 * settings across a power-down/up cycle */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		mii_reg &= ~MII_CR_POWER_DOWN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
static void e1000_power_down_phy(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* Power down the PHY so no link is implied when interface is down *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * The PHY cannot be powered down if any of the following is true *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 * (a) WoL is enabled
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	 * (b) AMT is active
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	 * (c) SoL/IDER session is active */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	   hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		u16 mii_reg = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
		case e1000_82540:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		case e1000_82545:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
				goto out;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
			goto out;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		mii_reg |= MII_CR_POWER_DOWN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		mdelay(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
out:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
void e1000_down(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	u32 rctl, tctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	/* signal that we're down so the interrupt handler does not
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 * reschedule our watchdog timer */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	set_bit(__E1000_DOWN, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	/* disable receives in the hardware */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	/* flush and sleep below */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	netif_tx_disable(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	/* disable transmits in the hardware */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	tctl = er32(TCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	tctl &= ~E1000_TCTL_EN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	ew32(TCTL, tctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* flush both disables and wait for them to finish */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	msleep(10);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	napi_disable(&adapter->napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	e1000_irq_disable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	del_timer_sync(&adapter->tx_fifo_stall_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	del_timer_sync(&adapter->watchdog_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	del_timer_sync(&adapter->phy_info_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	adapter->link_speed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	adapter->link_duplex = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	netif_carrier_off(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	e1000_clean_all_tx_rings(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	e1000_clean_all_rx_rings(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
void e1000_reinit_locked(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	WARN_ON(in_interrupt());
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		msleep(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	e1000_down(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	e1000_up(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	clear_bit(__E1000_RESETTING, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
void e1000_reset(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	bool legacy_pba_adjust = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	u16 hwm;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	/* Repartition Pba for greater than 9k mtu
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	 * To take effect CTRL.RST is required.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	case e1000_82540:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		legacy_pba_adjust = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		pba = E1000_PBA_48K;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	case e1000_82545:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	case e1000_82545_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		pba = E1000_PBA_48K;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		legacy_pba_adjust = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		pba = E1000_PBA_30K;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	case e1000_undefined:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	case e1000_num_macs:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	if (legacy_pba_adjust) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
			pba -= 8; /* allocate more FIFO for Tx */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		if (hw->mac_type == e1000_82547) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
			adapter->tx_fifo_head = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
			adapter->tx_fifo_size =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
			atomic_set(&adapter->tx_fifo_stall, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		/* adjust PBA for jumbo frames */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		ew32(PBA, pba);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		/* To maintain wire speed transmits, the Tx FIFO should be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		 * large enough to accommodate two full transmit packets,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		 * the Rx FIFO should be large enough to accommodate at least
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		 * one full receive packet and is similarly rounded up and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		 * expressed in KB. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		pba = er32(PBA);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		/* upper 16 bits has Tx packet buffer allocation size in KB */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		tx_space = pba >> 16;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		/* lower 16 bits has Rx packet buffer allocation size in KB */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		pba &= 0xffff;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		 * the tx fifo also stores 16 bytes of information about the tx
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		 * but don't include ethernet FCS because hardware appends it
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		min_tx_space = (hw->max_frame_size +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		                sizeof(struct e1000_tx_desc) -
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		                ETH_FCS_LEN) * 2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
		min_tx_space = ALIGN(min_tx_space, 1024);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		min_tx_space >>= 10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		/* software strips receive CRC, so leave room for it */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		min_rx_space = hw->max_frame_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		min_rx_space = ALIGN(min_rx_space, 1024);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		min_rx_space >>= 10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		/* If current Tx allocation is less than the min Tx FIFO size,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		 * and the min Tx FIFO size is less than the current Rx FIFO
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		 * allocation, take space away from current Rx allocation */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		if (tx_space < min_tx_space &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		    ((min_tx_space - tx_space) < pba)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			pba = pba - (min_tx_space - tx_space);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
			/* PCI/PCIx hardware has PBA alignment constraints */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
			case e1000_82545 ... e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
				pba &= ~(E1000_PBA_8K - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
			default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			/* if short on rx space, rx wins and must trump tx
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
			 * adjustment or use Early Receive if available */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
			if (pba < min_rx_space)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
				pba = min_rx_space;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	ew32(PBA, pba);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	 * flow control settings:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	 * The high water mark must be low enough to fit one full frame
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	 * (or the size used for early receive) above it in the Rx FIFO.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	 * Set it to the lower of:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	 * - 90% of the Rx FIFO size, and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	 * - the full Rx FIFO size minus the early receive size (for parts
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	 * - the full Rx FIFO size minus one full frame
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	hwm = min(((pba << 10) * 9 / 10),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		  ((pba << 10) - hw->max_frame_size));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	hw->fc_low_water = hw->fc_high_water - 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	hw->fc_send_xon = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	hw->fc = hw->original_fc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	/* Allow time for pending master requests to run */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	e1000_reset_hw(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	if (hw->mac_type >= e1000_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		ew32(WUC, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	if (e1000_init_hw(hw))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		e_err("Hardware Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	e1000_update_mng_vlan(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	if (hw->mac_type >= e1000_82544 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	    hw->autoneg == 1 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		u32 ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		/* clear phy power management bit if we are in gig only mode,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		 * which if enabled will attempt negotiation to 100Mb, which
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		 * can cause a loss of link at power off or driver unload */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		ctrl &= ~E1000_CTRL_SWDPIN3;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	e1000_reset_adaptive(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	e1000_phy_get_info(hw, &adapter->phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	e1000_release_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 *  Dump the eeprom for users having checksum issues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	struct ethtool_eeprom eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	const struct ethtool_ops *ops = netdev->ethtool_ops;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	u8 *data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	u16 csum_old, csum_new = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	eeprom.len = ops->get_eeprom_len(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	eeprom.offset = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	data = kmalloc(eeprom.len, GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	if (!data) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		pr_err("Unable to allocate memory to dump EEPROM data\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	ops->get_eeprom(netdev, &eeprom, data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		csum_new += data[i] + (data[i + 1] << 8);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	csum_new = EEPROM_SUM - csum_new;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	pr_err("/*********************/\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	pr_err("Calculated              : 0x%04x\n", csum_new);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	pr_err("Offset    Values\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	pr_err("========  ======\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	pr_err("Include this output when contacting your support provider.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	pr_err("This is not a software error! Something bad happened to\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	pr_err("result in further problems, possibly loss of data,\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	pr_err("corruption or system hangs!\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	pr_err("which is invalid and requires you to set the proper MAC\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	pr_err("address manually before continuing to enable this network\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	pr_err("device. Please inspect the EEPROM dump and report the\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	pr_err("/*********************/\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	kfree(data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
 * @pdev: PCI device information struct
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
 * Return true if an adapter needs ioport resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
static int e1000_is_need_ioport(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	switch (pdev->device) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	case E1000_DEV_ID_82540EM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	case E1000_DEV_ID_82540EM_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	case E1000_DEV_ID_82540EP:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	case E1000_DEV_ID_82540EP_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	case E1000_DEV_ID_82540EP_LP:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	case E1000_DEV_ID_82541EI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	case E1000_DEV_ID_82541EI_MOBILE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	case E1000_DEV_ID_82541ER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	case E1000_DEV_ID_82541ER_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	case E1000_DEV_ID_82541GI:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	case E1000_DEV_ID_82541GI_LF:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	case E1000_DEV_ID_82541GI_MOBILE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	case E1000_DEV_ID_82544EI_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	case E1000_DEV_ID_82544EI_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	case E1000_DEV_ID_82544GC_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	case E1000_DEV_ID_82544GC_LOM:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	case E1000_DEV_ID_82545EM_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	case E1000_DEV_ID_82545EM_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	case E1000_DEV_ID_82546EB_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	case E1000_DEV_ID_82546EB_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		return true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		return false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
static const struct net_device_ops e1000_netdev_ops = {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	.ndo_open		= e1000_open,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	.ndo_stop		= e1000_close,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	.ndo_start_xmit		= e1000_xmit_frame,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	.ndo_get_stats		= e1000_get_stats,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	.ndo_set_rx_mode	= e1000_set_rx_mode,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	.ndo_set_mac_address	= e1000_set_mac,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	.ndo_tx_timeout 	= e1000_tx_timeout,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	.ndo_change_mtu		= e1000_change_mtu,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	.ndo_do_ioctl		= e1000_ioctl,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	.ndo_validate_addr	= eth_validate_addr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
#ifdef CONFIG_NET_POLL_CONTROLLER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	.ndo_poll_controller	= e1000_netpoll,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
 * e1000_probe - Device Initialization Routine
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
 * @pdev: PCI device information struct
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
 * @ent: entry in e1000_pci_tbl
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
 * Returns 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
 * e1000_probe initializes an adapter identified by a pci_dev structure.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 * The OS initialization, configuring of the adapter private structure,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 * and a hardware reset occur.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
static int __devinit e1000_probe(struct pci_dev *pdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
				 const struct pci_device_id *ent)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	struct net_device *netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	struct e1000_adapter *adapter;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct e1000_hw *hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	static int cards_found = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	int i, err, pci_using_dac;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	u16 eeprom_data = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	int bars, need_ioport;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	/* do not allocate ioport bars when not needed */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	need_ioport = e1000_is_need_ioport(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	if (need_ioport) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		err = pci_enable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		err = pci_enable_device_mem(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	    !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		pci_using_dac = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			err = dma_set_coherent_mask(&pdev->dev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
						    DMA_BIT_MASK(32));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
			if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
				pr_err("No usable DMA config, aborting\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
				goto err_dma;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		pci_using_dac = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		goto err_pci_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	pci_set_master(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	err = pci_save_state(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		goto err_alloc_etherdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	err = -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	if (!netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		goto err_alloc_etherdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	SET_NETDEV_DEV(netdev, &pdev->dev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	pci_set_drvdata(pdev, netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	adapter->netdev = netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	adapter->pdev = pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	adapter->msg_enable = (1 << debug) - 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	adapter->bars = bars;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	adapter->need_ioport = need_ioport;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	hw->back = adapter;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	err = -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	if (!hw->hw_addr)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		goto err_ioremap;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	if (adapter->need_ioport) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		for (i = BAR_1; i <= BAR_5; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
			if (pci_resource_len(pdev, i) == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
				continue;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
				hw->io_base = pci_resource_start(pdev, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	netdev->netdev_ops = &e1000_netdev_ops;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	e1000_set_ethtool_ops(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	netdev->watchdog_timeo = 5 * HZ;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	adapter->bd_number = cards_found;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	/* setup the private structure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	err = e1000_sw_init(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		goto err_sw_init;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	err = -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	if (hw->mac_type >= e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		netdev->features = NETIF_F_SG |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
				   NETIF_F_HW_CSUM |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
				   NETIF_F_HW_VLAN_TX |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
				   NETIF_F_HW_VLAN_RX |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
				   NETIF_F_HW_VLAN_FILTER;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	if ((hw->mac_type >= e1000_82544) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	   (hw->mac_type != e1000_82547))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		netdev->features |= NETIF_F_TSO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	if (pci_using_dac)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
		netdev->features |= NETIF_F_HIGHDMA;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	netdev->vlan_features |= NETIF_F_TSO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	netdev->vlan_features |= NETIF_F_HW_CSUM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	netdev->vlan_features |= NETIF_F_SG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	/* initialize eeprom parameters */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	if (e1000_init_eeprom_params(hw)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		e_err("EEPROM initialization failed\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		goto err_eeprom;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	/* before reading the EEPROM, reset the controller to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	 * put the device in a known good starting state */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	e1000_reset_hw(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	/* make sure the EEPROM is good */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	if (e1000_validate_eeprom_checksum(hw) < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		e_err("The EEPROM Checksum Is Not Valid\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		e1000_dump_eeprom(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		 * set MAC address to all zeroes to invalidate and temporary
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		 * disable this device for the user. This blocks regular
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		 * traffic while still permitting ethtool ioctls from reaching
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		 * the hardware as well as allowing the user to run the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		 * interface after manually setting a hw addr using
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		 * `ip set address`
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		memset(hw->mac_addr, 0, netdev->addr_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
		/* copy the MAC address out of the EEPROM */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		if (e1000_read_mac_addr(hw))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
			e_err("EEPROM Read Error\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	/* don't block initalization here due to bad MAC address */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	if (!is_valid_ether_addr(netdev->perm_addr))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		e_err("Invalid MAC Address\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	e1000_get_bus_info(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	init_timer(&adapter->tx_fifo_stall_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	init_timer(&adapter->watchdog_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	adapter->watchdog_timer.function = &e1000_watchdog;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	adapter->watchdog_timer.data = (unsigned long) adapter;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	init_timer(&adapter->phy_info_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	adapter->phy_info_timer.function = &e1000_update_phy_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	adapter->phy_info_timer.data = (unsigned long)adapter;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	e1000_check_options(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	/* Initial Wake on LAN setting
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	 * If APM wake is enabled in the EEPROM,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	 * enable the ACPI Magic Packet filter
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	case e1000_82543:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		e1000_read_eeprom(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	case e1000_82546:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	case e1000_82546_rev_3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
			e1000_read_eeprom(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		/* Fall Through */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		e1000_read_eeprom(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	if (eeprom_data & eeprom_apme_mask)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		adapter->eeprom_wol |= E1000_WUFC_MAG;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	/* now that we have the eeprom settings, apply the special cases
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	 * where the eeprom may be wrong or the board simply won't support
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	 * wake on lan on a particular port */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	switch (pdev->device) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	case E1000_DEV_ID_82546GB_PCIE:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		adapter->eeprom_wol = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	case E1000_DEV_ID_82546EB_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	case E1000_DEV_ID_82546GB_FIBER:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		/* Wake events only supported on port A for dual fiber
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		 * regardless of eeprom setting */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			adapter->eeprom_wol = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		/* if quad port adapter, disable WoL on all but port A */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		if (global_quad_port_a != 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
			adapter->eeprom_wol = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
			adapter->quad_port_a = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		/* Reset for multiple quad port adapters */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		if (++global_quad_port_a == 4)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
			global_quad_port_a = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	/* initialize the wol settings based on the eeprom settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	adapter->wol = adapter->eeprom_wol;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	/* reset the hardware with the new settings */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	strcpy(netdev->name, "eth%d");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	err = register_netdev(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		goto err_register;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	/* print bus type/speed/width info */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	e_info("(PCI%s:%dMHz:%d-bit) %pM\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	       netdev->dev_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	/* carrier off reporting is important to ethtool even BEFORE open */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	netif_carrier_off(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	e_info("Intel(R) PRO/1000 Network Connection\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	cards_found++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
err_register:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
err_eeprom:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	e1000_phy_hw_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	if (hw->flash_address)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		iounmap(hw->flash_address);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	kfree(adapter->tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	kfree(adapter->rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
err_sw_init:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	iounmap(hw->hw_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
err_ioremap:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	free_netdev(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
err_alloc_etherdev:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	pci_release_selected_regions(pdev, bars);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
err_pci_reg:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
err_dma:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	pci_disable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
 * e1000_remove - Device Removal Routine
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
 * @pdev: PCI device information struct
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
 * e1000_remove is called by the PCI subsystem to alert the driver
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
 * that it should release a PCI device.  The could be caused by a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
 * Hot-Plug event, or because the driver is going to be removed from
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
 * memory.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
static void __devexit e1000_remove(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	set_bit(__E1000_DOWN, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	del_timer_sync(&adapter->tx_fifo_stall_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	del_timer_sync(&adapter->watchdog_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	del_timer_sync(&adapter->phy_info_timer);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	cancel_work_sync(&adapter->reset_task);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	e1000_release_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	unregister_netdev(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	e1000_phy_hw_reset(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	kfree(adapter->tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	kfree(adapter->rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	iounmap(hw->hw_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	if (hw->flash_address)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		iounmap(hw->flash_address);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	pci_release_selected_regions(pdev, adapter->bars);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	free_netdev(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	pci_disable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
 * @adapter: board private structure to initialize
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
 * e1000_sw_init initializes the Adapter private data structure.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
 * Fields are initialized based on PCI device information and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
 * OS network device settings (MTU size).
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	/* PCI config space info */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	hw->vendor_id = pdev->vendor;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	hw->device_id = pdev->device;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	hw->subsystem_id = pdev->subsystem_device;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	hw->revision_id = pdev->revision;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	hw->max_frame_size = netdev->mtu +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	/* identify the MAC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	if (e1000_set_mac_type(hw)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		e_err("Unknown MAC Type\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		return -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	case e1000_82541:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	case e1000_82547:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	case e1000_82541_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	case e1000_82547_rev_2:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		hw->phy_init_script = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	e1000_set_media_type(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	hw->wait_autoneg_complete = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	hw->tbi_compatibility_en = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	hw->adaptive_ifs = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	/* Copper options */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		hw->mdix = AUTO_ALL_MODES;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		hw->disable_polarity_correction = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		hw->master_slave = E1000_MASTER_SLAVE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	adapter->num_tx_queues = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	adapter->num_rx_queues = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	if (e1000_alloc_queues(adapter)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		e_err("Unable to allocate memory for queues\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	/* Explicitly disable IRQ since the NIC can be in any state. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	e1000_irq_disable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	spin_lock_init(&adapter->stats_lock);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	set_bit(__E1000_DOWN, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 * e1000_alloc_queues - Allocate memory for all rings
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
 * @adapter: board private structure to initialize
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
 * We allocate one ring per queue at run-time since we don't know the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
 * number of queues at compile-time.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	if (!adapter->tx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	if (!adapter->rx_ring) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		kfree(adapter->tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
 * e1000_open - Called when a network interface is made active
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
 * Returns 0 on success, negative value on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
 * The open entry point is called when a network interface is made
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
 * active by the system (IFF_UP).  At this point all resources needed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
 * for transmit and receive operations are allocated, the interrupt
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
 * handler is registered with the OS, the watchdog timer is started,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
 * and the stack is notified that the interface is ready.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
static int e1000_open(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	int err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	/* disallow open during test */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	if (test_bit(__E1000_TESTING, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		return -EBUSY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	netif_carrier_off(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	/* allocate transmit descriptors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	err = e1000_setup_all_tx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		goto err_setup_tx;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	/* allocate receive descriptors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	err = e1000_setup_all_rx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		goto err_setup_rx;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	e1000_power_up_phy(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	if ((hw->mng_cookie.status &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		e1000_update_mng_vlan(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	/* before we allocate an interrupt, we must be ready to handle it.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	 * as soon as we call pci_request_irq, so we have to setup our
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	 * clean_rx handler before we do so.  */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	e1000_configure(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	err = e1000_request_irq(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		goto err_req_irq;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	/* From here on the code is the same as e1000_up() */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	clear_bit(__E1000_DOWN, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	napi_enable(&adapter->napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	netif_start_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	/* fire a link status change interrupt to start the watchdog */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	ew32(ICS, E1000_ICS_LSC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
err_req_irq:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	e1000_power_down_phy(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	e1000_free_all_rx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
err_setup_rx:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	e1000_free_all_tx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
err_setup_tx:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 * e1000_close - Disables a network interface
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 * Returns 0, this is not allowed to fail
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * The close entry point is called when an interface is de-activated
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 * by the OS.  The hardware is still under the drivers control, but
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 * needs to be disabled.  A global MAC reset is issued to stop the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 * hardware, and all transmit and receive resources are freed.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
static int e1000_close(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	e1000_down(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	e1000_power_down_phy(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	e1000_free_irq(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	e1000_free_all_tx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	e1000_free_all_rx_resources(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	/* kill manageability vlan ID if supported, but not if a vlan with
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	 * the same ID is registered on the host OS (let 8021q kill it) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	if ((hw->mng_cookie.status &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	     !(adapter->vlgrp &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 * @adapter: address of board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 * @start: address of beginning of memory
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
 * @len: length of memory
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
				  unsigned long len)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	unsigned long begin = (unsigned long)start;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	unsigned long end = begin + len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	/* First rev 82545 and 82546 need to not allow any memory
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	 * write location to cross 64k boundary due to errata 23 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	if (hw->mac_type == e1000_82545 ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
	    hw->mac_type == e1000_82546) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	return true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
 * @txdr:    tx descriptor ring (for a specific queue) to setup
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
 * Return 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
				    struct e1000_tx_ring *txdr)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	int size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	size = sizeof(struct e1000_buffer) * txdr->count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	txdr->buffer_info = vmalloc(size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	if (!txdr->buffer_info) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		e_err("Unable to allocate memory for the Tx descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	memset(txdr->buffer_info, 0, size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	/* round up to nearest 4K */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	txdr->size = ALIGN(txdr->size, 4096);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
					GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	if (!txdr->desc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
setup_tx_desc_die:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		vfree(txdr->buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		e_err("Unable to allocate memory for the Tx descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	/* Fix for errata 23, can't cross 64kB boundary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		void *olddesc = txdr->desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		dma_addr_t olddma = txdr->dma;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		e_err("txdr align check failed: %u bytes at %p\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		      txdr->size, txdr->desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		/* Try again, without freeing the previous */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
						&txdr->dma, GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		/* Failed allocation, critical failure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
		if (!txdr->desc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
			goto setup_tx_desc_die;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
			/* give up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
					  txdr->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
			e_err("Unable to allocate aligned memory "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			      "for the transmit descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			vfree(txdr->buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
			return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			/* Free old allocation, new allocation was successful */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	memset(txdr->desc, 0, txdr->size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	txdr->next_to_use = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	txdr->next_to_clean = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 * 				  (Descriptors) for all queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
 * Return 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	int i, err = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	for (i = 0; i < adapter->num_tx_queues; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
			e_err("Allocation for Tx Queue %u failed\n", i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			for (i-- ; i >= 0; i--)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
				e1000_free_tx_resources(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
							&adapter->tx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
 * Configure the Tx unit of the MAC after a reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
static void e1000_configure_tx(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	u64 tdba;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	u32 tdlen, tctl, tipg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	u32 ipgr1, ipgr2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	/* Setup the HW Tx Head and Tail descriptor pointers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	switch (adapter->num_tx_queues) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	case 1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		tdba = adapter->tx_ring[0].dma;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
		tdlen = adapter->tx_ring[0].count *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
			sizeof(struct e1000_tx_desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		ew32(TDLEN, tdlen);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		ew32(TDBAH, (tdba >> 32));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		ew32(TDT, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		ew32(TDH, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	/* Set the default values for the Tx Inter Packet Gap timer */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	if ((hw->media_type == e1000_media_type_fiber ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	     hw->media_type == e1000_media_type_internal_serdes))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	case e1000_82542_rev2_0:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	case e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		tipg = DEFAULT_82542_TIPG_IPGT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	ew32(TIPG, tipg);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	/* Set the Tx Interrupt Delay register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	ew32(TIDV, adapter->tx_int_delay);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	if (hw->mac_type >= e1000_82540)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		ew32(TADV, adapter->tx_abs_int_delay);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	/* Program the Transmit Control Register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	tctl = er32(TCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	tctl &= ~E1000_TCTL_CT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	e1000_config_collision_dist(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	/* Setup Transmit Descriptor Settings for eop descriptor */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	/* only set IDE if we are delaying interrupts using the timers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	if (adapter->tx_int_delay)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	if (hw->mac_type < e1000_82543)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	/* Cache if we're 82544 running in PCI-X because we'll
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	 * need this to apply a workaround later in the send path. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	if (hw->mac_type == e1000_82544 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	    hw->bus_type == e1000_bus_type_pcix)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		adapter->pcix_82544 = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	ew32(TCTL, tctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
 * Returns 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
				    struct e1000_rx_ring *rxdr)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	int size, desc_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	size = sizeof(struct e1000_buffer) * rxdr->count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	rxdr->buffer_info = vmalloc(size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	if (!rxdr->buffer_info) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
		e_err("Unable to allocate memory for the Rx descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	memset(rxdr->buffer_info, 0, size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	desc_len = sizeof(struct e1000_rx_desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	/* Round up to nearest 4K */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	rxdr->size = rxdr->count * desc_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	rxdr->size = ALIGN(rxdr->size, 4096);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
					GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (!rxdr->desc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		e_err("Unable to allocate memory for the Rx descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
setup_rx_desc_die:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		vfree(rxdr->buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		return -ENOMEM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	/* Fix for errata 23, can't cross 64kB boundary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		void *olddesc = rxdr->desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		dma_addr_t olddma = rxdr->dma;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		e_err("rxdr align check failed: %u bytes at %p\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		      rxdr->size, rxdr->desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		/* Try again, without freeing the previous */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
						&rxdr->dma, GFP_KERNEL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		/* Failed allocation, critical failure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		if (!rxdr->desc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			e_err("Unable to allocate memory for the Rx descriptor "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
			      "ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
			goto setup_rx_desc_die;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			/* give up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
					  rxdr->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
			e_err("Unable to allocate aligned memory for the Rx "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
			      "descriptor ring\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			goto setup_rx_desc_die;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
			/* Free old allocation, new allocation was successful */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
					  olddma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	memset(rxdr->desc, 0, rxdr->size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	rxdr->next_to_clean = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	rxdr->next_to_use = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	rxdr->rx_skb_top = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 * 				  (Descriptors) for all queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
 * Return 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	int i, err = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	for (i = 0; i < adapter->num_rx_queues; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			e_err("Allocation for Rx Queue %u failed\n", i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			for (i-- ; i >= 0; i--)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
				e1000_free_rx_resources(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
							&adapter->rx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
 * e1000_setup_rctl - configure the receive control registers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
 * @adapter: Board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
static void e1000_setup_rctl(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	u32 rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	if (hw->tbi_compatibility_on == 1)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		rctl |= E1000_RCTL_SBP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		rctl &= ~E1000_RCTL_SBP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
		rctl &= ~E1000_RCTL_LPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		rctl |= E1000_RCTL_LPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	/* Setup buffer sizes */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	rctl &= ~E1000_RCTL_SZ_4096;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	rctl |= E1000_RCTL_BSEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	switch (adapter->rx_buffer_len) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		case E1000_RXBUFFER_2048:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
			rctl |= E1000_RCTL_SZ_2048;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
			rctl &= ~E1000_RCTL_BSEX;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		case E1000_RXBUFFER_4096:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			rctl |= E1000_RCTL_SZ_4096;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
		case E1000_RXBUFFER_8192:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			rctl |= E1000_RCTL_SZ_8192;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		case E1000_RXBUFFER_16384:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
			rctl |= E1000_RCTL_SZ_16384;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
 * Configure the Rx unit of the MAC after a reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
static void e1000_configure_rx(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	u64 rdba;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	u32 rdlen, rctl, rxcsum;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		rdlen = adapter->rx_ring[0].count *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		        sizeof(struct e1000_rx_desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		rdlen = adapter->rx_ring[0].count *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		        sizeof(struct e1000_rx_desc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		adapter->clean_rx = e1000_clean_rx_irq;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	/* disable receives while setting up the descriptors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	/* set the Receive Delay Timer Register */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	ew32(RDTR, adapter->rx_int_delay);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	if (hw->mac_type >= e1000_82540) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		ew32(RADV, adapter->rx_abs_int_delay);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		if (adapter->itr_setting != 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			ew32(ITR, 1000000000 / (adapter->itr * 256));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	 * the Base and Length of the Rx Descriptor Ring */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	switch (adapter->num_rx_queues) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	case 1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		rdba = adapter->rx_ring[0].dma;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		ew32(RDLEN, rdlen);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		ew32(RDBAH, (rdba >> 32));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		ew32(RDT, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		ew32(RDH, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	if (hw->mac_type >= e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		rxcsum = er32(RXCSUM);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		if (adapter->rx_csum)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
			rxcsum |= E1000_RXCSUM_TUOFL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
			/* don't need to clear IPPCSE as it defaults to 0 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			rxcsum &= ~E1000_RXCSUM_TUOFL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		ew32(RXCSUM, rxcsum);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	/* Enable Receives */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 * e1000_free_tx_resources - Free Tx Resources per Queue
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
 * @tx_ring: Tx descriptor ring for a specific queue
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
 * Free all transmit software resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
				    struct e1000_tx_ring *tx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	e1000_clean_tx_ring(adapter, tx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	vfree(tx_ring->buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	tx_ring->buffer_info = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
			  tx_ring->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	tx_ring->desc = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
 * Free all transmit software resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	for (i = 0; i < adapter->num_tx_queues; i++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
					     struct e1000_buffer *buffer_info)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	if (buffer_info->dma) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		if (buffer_info->mapped_as_page)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
				       buffer_info->length, DMA_TO_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
					 buffer_info->length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
					 DMA_TO_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	if (buffer_info->skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		dev_kfree_skb_any(buffer_info->skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	buffer_info->time_stamp = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	/* buffer_info must be completely set up in the transmit path */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
 * e1000_clean_tx_ring - Free Tx Buffers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
 * @tx_ring: ring to be cleaned
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				struct e1000_tx_ring *tx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	unsigned long size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	/* Free all the Tx ring sk_buffs */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	for (i = 0; i < tx_ring->count; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	size = sizeof(struct e1000_buffer) * tx_ring->count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	memset(tx_ring->buffer_info, 0, size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	/* Zero out the descriptor ring */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	memset(tx_ring->desc, 0, tx_ring->size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	tx_ring->next_to_use = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	tx_ring->next_to_clean = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	tx_ring->last_tx_tso = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	writel(0, hw->hw_addr + tx_ring->tdh);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	writel(0, hw->hw_addr + tx_ring->tdt);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	for (i = 0; i < adapter->num_tx_queues; i++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
 * e1000_free_rx_resources - Free Rx Resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 * @rx_ring: ring to clean the resources from
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 * Free all receive software resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
				    struct e1000_rx_ring *rx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	e1000_clean_rx_ring(adapter, rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	vfree(rx_ring->buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	rx_ring->buffer_info = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
			  rx_ring->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	rx_ring->desc = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * Free all receive software resources
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	for (i = 0; i < adapter->num_rx_queues; i++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
 * @rx_ring: ring to free buffers from
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
				struct e1000_rx_ring *rx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	unsigned long size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	/* Free all the Rx ring sk_buffs */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	for (i = 0; i < rx_ring->count; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		if (buffer_info->dma &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		    adapter->clean_rx == e1000_clean_rx_irq) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			dma_unmap_single(&pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			                 buffer_info->length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
					 DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
		} else if (buffer_info->dma &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			dma_unmap_page(&pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
				       buffer_info->length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
				       DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		if (buffer_info->page) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
			put_page(buffer_info->page);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
			buffer_info->page = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		if (buffer_info->skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
			dev_kfree_skb(buffer_info->skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
			buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	/* there also may be some cached data from a chained receive */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	if (rx_ring->rx_skb_top) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
		dev_kfree_skb(rx_ring->rx_skb_top);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		rx_ring->rx_skb_top = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	size = sizeof(struct e1000_buffer) * rx_ring->count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	memset(rx_ring->buffer_info, 0, size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	/* Zero out the descriptor ring */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	memset(rx_ring->desc, 0, rx_ring->size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	rx_ring->next_to_clean = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	rx_ring->next_to_use = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	writel(0, hw->hw_addr + rx_ring->rdh);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	writel(0, hw->hw_addr + rx_ring->rdt);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	for (i = 0; i < adapter->num_rx_queues; i++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
 * and memory write and invalidate disabled for certain operations
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	u32 rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	e1000_pci_clear_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	rctl |= E1000_RCTL_RST;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	mdelay(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		e1000_clean_all_rx_rings(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	u32 rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	rctl &= ~E1000_RCTL_RST;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	mdelay(5);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		e1000_pci_set_mwi(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	if (netif_running(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		/* No need to loop, because 82542 supports only 1 queue */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		e1000_configure_rx(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
 * e1000_set_mac - Change the Ethernet Address of the NIC
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
 * @p: pointer to an address structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
 * Returns 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
static int e1000_set_mac(struct net_device *netdev, void *p)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	struct sockaddr *addr = p;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	if (!is_valid_ether_addr(addr->sa_data))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		return -EADDRNOTAVAIL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	/* 82542 2.0 needs to be in reset to write receive address registers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
		e1000_enter_82542_rst(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	e1000_rar_set(hw, hw->mac_addr, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		e1000_leave_82542_rst(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
 * The set_rx_mode entry point is called whenever the unicast or multicast
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
 * address lists or the network interface flags are updated. This routine is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
 * responsible for configuring the hardware for proper unicast, multicast,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
 * promiscuous mode, and all-multi behavior.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
static void e1000_set_rx_mode(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	struct netdev_hw_addr *ha;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	bool use_uc = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	u32 rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	u32 hash_value;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	int i, rar_entries = E1000_RAR_ENTRIES;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	if (!mcarray) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		e_err("memory allocation failed\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	/* Check for Promiscuous and All Multicast modes */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	if (netdev->flags & IFF_PROMISC) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		rctl &= ~E1000_RCTL_VFE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		if (netdev->flags & IFF_ALLMULTI)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
			rctl |= E1000_RCTL_MPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			rctl &= ~E1000_RCTL_MPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
		/* Enable VLAN filter if there is a VLAN */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
		if (adapter->vlgrp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
			rctl |= E1000_RCTL_VFE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	if (netdev_uc_count(netdev) > rar_entries - 1) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		rctl |= E1000_RCTL_UPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	} else if (!(netdev->flags & IFF_PROMISC)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
		rctl &= ~E1000_RCTL_UPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
		use_uc = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
	/* 82542 2.0 needs to be in reset to write receive address registers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		e1000_enter_82542_rst(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	/* load the first 14 addresses into the exact filters 1-14. Unicast
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	 * addresses take precedence to avoid disabling unicast filtering
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	 * when possible.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	 * RAR 0 is used for the station MAC adddress
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	 * if there are not 14 addresses, go ahead and clear the filters
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	i = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	if (use_uc)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
		netdev_for_each_uc_addr(ha, netdev) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			if (i == rar_entries)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			e1000_rar_set(hw, ha->addr, i++);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	netdev_for_each_mc_addr(ha, netdev) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
		if (i == rar_entries) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			/* load any remaining addresses into the hash table */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
			u32 hash_reg, hash_bit, mta;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
			hash_reg = (hash_value >> 5) & 0x7F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			hash_bit = hash_value & 0x1F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
			mta = (1 << hash_bit);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			mcarray[hash_reg] |= mta;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			e1000_rar_set(hw, ha->addr, i++);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	for (; i < rar_entries; i++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	/* write the hash table completely, write from bottom to avoid
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	 * both stupid write combining chipsets, and flushing each write */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		 * If we are on an 82544 has an errata where writing odd
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		 * offsets overwrites the previous even offset, but writing
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
		 * backwards over the range solves the issue by always
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		 * writing the odd offset first
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	if (hw->mac_type == e1000_82542_rev2_0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		e1000_leave_82542_rst(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	kfree(mcarray);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
/* Need to wait a few seconds after link up to get diagnostic information from
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
 * the phy */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
static void e1000_update_phy_info(unsigned long data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	e1000_phy_get_info(hw, &adapter->phy_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
 * e1000_82547_tx_fifo_stall - Timer Call-back
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
 * @data: pointer to adapter cast into an unsigned long
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
static void e1000_82547_tx_fifo_stall(unsigned long data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	u32 tctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	if (atomic_read(&adapter->tx_fifo_stall)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
		if ((er32(TDT) == er32(TDH)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
		   (er32(TDFT) == er32(TDFH)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
		   (er32(TDFTS) == er32(TDFHS))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
			tctl = er32(TCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
			ew32(TDFT, adapter->tx_head_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
			ew32(TDFH, adapter->tx_head_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
			ew32(TDFTS, adapter->tx_head_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
			ew32(TDFHS, adapter->tx_head_addr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
			ew32(TCTL, tctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
			E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
			adapter->tx_fifo_head = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
			atomic_set(&adapter->tx_fifo_stall, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
			netif_wake_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
bool e1000_has_link(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	bool link_active = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	/* get_link_status is set on LSC (link status) interrupt or
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	 * rx sequence error interrupt.  get_link_status will stay
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	 * false until the e1000_check_for_link establishes link
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	 * for copper adapters ONLY
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	switch (hw->media_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	case e1000_media_type_copper:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
		if (hw->get_link_status) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
			e1000_check_for_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
			link_active = !hw->get_link_status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			link_active = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	case e1000_media_type_fiber:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		e1000_check_for_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	case e1000_media_type_internal_serdes:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		e1000_check_for_link(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		link_active = hw->serdes_has_link;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	return link_active;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 * e1000_watchdog - Timer Call-back
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 * @data: pointer to adapter cast into an unsigned long
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
static void e1000_watchdog(unsigned long data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	struct e1000_tx_ring *txdr = adapter->tx_ring;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	u32 link, tctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	link = e1000_has_link(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	if ((netif_carrier_ok(netdev)) && link)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
		goto link_up;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	if (link) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
		if (!netif_carrier_ok(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
			u32 ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
			bool txb2b = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
			/* update snapshot of PHY registers on LSC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
			e1000_get_speed_and_duplex(hw,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
			                           &adapter->link_speed,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
			                           &adapter->link_duplex);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
			ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			pr_info("%s NIC Link is Up %d Mbps %s, "
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
				"Flow Control: %s\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
				netdev->name,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
				adapter->link_speed,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
				adapter->link_duplex == FULL_DUPLEX ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
				"Full Duplex" : "Half Duplex",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
				E1000_CTRL_TFCE) ? "TX" : "None")));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			/* adjust timeout factor according to speed/duplex */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			adapter->tx_timeout_factor = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
			switch (adapter->link_speed) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
			case SPEED_10:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
				txb2b = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
				adapter->tx_timeout_factor = 16;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
			case SPEED_100:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
				txb2b = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
				/* maybe add some timeout factor ? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
			/* enable transmits in the hardware */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
			tctl = er32(TCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
			tctl |= E1000_TCTL_EN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
			ew32(TCTL, tctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
			netif_carrier_on(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
			if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
				mod_timer(&adapter->phy_info_timer,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
				          round_jiffies(jiffies + 2 * HZ));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
			adapter->smartspeed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		if (netif_carrier_ok(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
			adapter->link_speed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			adapter->link_duplex = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
			pr_info("%s NIC Link is Down\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
				netdev->name);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
			netif_carrier_off(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
			if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
				mod_timer(&adapter->phy_info_timer,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
				          round_jiffies(jiffies + 2 * HZ));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		e1000_smartspeed(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
link_up:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	e1000_update_stats(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	adapter->tpt_old = adapter->stats.tpt;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	adapter->colc_old = adapter->stats.colc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	adapter->gorcl_old = adapter->stats.gorcl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	adapter->gotcl_old = adapter->stats.gotcl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	e1000_update_adaptive(hw);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	if (!netif_carrier_ok(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			/* We've lost link, so the controller stops DMA,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			 * but we've got queued Tx work that's never going
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			 * to get done, so reset controller to flush Tx.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			 * (Do the reset outside of interrupt context). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			adapter->tx_timeout_count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			schedule_work(&adapter->reset_task);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			/* return immediately since reset is imminent */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	/* Simple mode for Interrupt Throttle Rate (ITR) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		 * Total asymmetrical Tx or Rx gets ITR=8000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		 * everyone else is between 2000-8000.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		u32 dif = (adapter->gotcl > adapter->gorcl ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			    adapter->gotcl - adapter->gorcl :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
			    adapter->gorcl - adapter->gotcl) / 10000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		ew32(ITR, 1000000000 / (itr * 256));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	/* Cause software interrupt to ensure rx ring is cleaned */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	ew32(ICS, E1000_ICS_RXDMT0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	/* Force detection of hung controller every watchdog period */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	adapter->detect_tx_hung = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	/* Reset the timer */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		mod_timer(&adapter->watchdog_timer,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
		          round_jiffies(jiffies + 2 * HZ));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
enum latency_range {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	lowest_latency = 0,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	low_latency = 1,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	bulk_latency = 2,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	latency_invalid = 255
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
};
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
 * e1000_update_itr - update the dynamic ITR value based on statistics
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
 * @adapter: pointer to adapter
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
 * @itr_setting: current adapter->itr
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
 * @packets: the number of packets during this measurement interval
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
 * @bytes: the number of bytes during this measurement interval
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
 *      Stores a new ITR value based on packets and byte
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
 *      counts during the last interrupt.  The advantage of per interrupt
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
 *      computation is faster updates and more accurate ITR for the current
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
 *      traffic pattern.  Constants in this function were computed
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
 *      based on theoretical maximum wire speed and thresholds were set based
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
 *      on testing data as well as attempting to minimize response time
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
 *      while increasing bulk throughput.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
 *      this functionality is controlled by the InterruptThrottleRate module
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 *      parameter (see e1000_param.c)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
				     u16 itr_setting, int packets, int bytes)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	unsigned int retval = itr_setting;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	if (unlikely(hw->mac_type < e1000_82540))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
		goto update_itr_done;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	if (packets == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		goto update_itr_done;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	switch (itr_setting) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	case lowest_latency:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		/* jumbo frames get bulk treatment*/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		if (bytes/packets > 8000)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
			retval = bulk_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		else if ((packets < 5) && (bytes > 512))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
			retval = low_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	case low_latency:  /* 50 usec aka 20000 ints/s */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		if (bytes > 10000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			/* jumbo frames need bulk latency setting */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
			if (bytes/packets > 8000)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
				retval = bulk_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			else if ((packets < 10) || ((bytes/packets) > 1200))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
				retval = bulk_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			else if ((packets > 35))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
				retval = lowest_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		} else if (bytes/packets > 2000)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
			retval = bulk_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		else if (packets <= 2 && bytes < 512)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			retval = lowest_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	case bulk_latency: /* 250 usec aka 4000 ints/s */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		if (bytes > 25000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			if (packets > 35)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
				retval = low_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		} else if (bytes < 6000) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
			retval = low_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
update_itr_done:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	return retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
static void e1000_set_itr(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	u16 current_itr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	u32 new_itr = adapter->itr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	if (unlikely(hw->mac_type < e1000_82540))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	if (unlikely(adapter->link_speed != SPEED_1000)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		current_itr = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		new_itr = 4000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		goto set_itr_now;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	adapter->tx_itr = e1000_update_itr(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	                            adapter->tx_itr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	                            adapter->total_tx_packets,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	                            adapter->total_tx_bytes);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		adapter->tx_itr = low_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	adapter->rx_itr = e1000_update_itr(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	                            adapter->rx_itr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	                            adapter->total_rx_packets,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	                            adapter->total_rx_bytes);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		adapter->rx_itr = low_latency;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	switch (current_itr) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	/* counts and packets in update_itr are dependent on these numbers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	case lowest_latency:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		new_itr = 70000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	case low_latency:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		new_itr = 20000; /* aka hwitr = ~200 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	case bulk_latency:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		new_itr = 4000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
set_itr_now:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	if (new_itr != adapter->itr) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		/* this attempts to bias the interrupt rate towards Bulk
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		 * by adding intermediate steps when interrupt rate is
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		 * increasing */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		new_itr = new_itr > adapter->itr ?
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		             min(adapter->itr + (new_itr >> 2), new_itr) :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		             new_itr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
		adapter->itr = new_itr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		ew32(ITR, 1000000000 / (new_itr * 256));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
#define E1000_TX_FLAGS_CSUM		0x00000001
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
#define E1000_TX_FLAGS_VLAN		0x00000002
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
#define E1000_TX_FLAGS_TSO		0x00000004
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
#define E1000_TX_FLAGS_IPV4		0x00000008
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
#define E1000_TX_FLAGS_VLAN_SHIFT	16
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
static int e1000_tso(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	struct e1000_context_desc *context_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	u32 cmd_length = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	u16 ipcse = 0, tucse, mss;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	int err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	if (skb_is_gso(skb)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		if (skb_header_cloned(skb)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
				return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		mss = skb_shinfo(skb)->gso_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		if (skb->protocol == htons(ETH_P_IP)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
			struct iphdr *iph = ip_hdr(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
			iph->tot_len = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
			iph->check = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
								 iph->daddr, 0,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
								 IPPROTO_TCP,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
								 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			cmd_length = E1000_TXD_CMD_IP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
			ipcse = skb_transport_offset(skb) - 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			ipv6_hdr(skb)->payload_len = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			tcp_hdr(skb)->check =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
						 &ipv6_hdr(skb)->daddr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
						 0, IPPROTO_TCP, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
			ipcse = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		ipcss = skb_network_offset(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		tucss = skb_transport_offset(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		tucse = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		i = tx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		context_desc->upper_setup.tcp_fields.tucss = tucss;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		context_desc->upper_setup.tcp_fields.tucso = tucso;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		buffer_info->time_stamp = jiffies;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		buffer_info->next_to_watch = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		if (++i == tx_ring->count) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
		tx_ring->next_to_use = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		return true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	return false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
static bool e1000_tx_csum(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	struct e1000_context_desc *context_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	u8 css;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	u32 cmd_len = E1000_TXD_CMD_DEXT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	if (skb->ip_summed != CHECKSUM_PARTIAL)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		return false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	switch (skb->protocol) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	case cpu_to_be16(ETH_P_IP):
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			cmd_len |= E1000_TXD_CMD_TCP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	case cpu_to_be16(ETH_P_IPV6):
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		/* XXX not handling all IPV6 headers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
			cmd_len |= E1000_TXD_CMD_TCP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		if (unlikely(net_ratelimit()))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			e_warn("checksum_partial proto=%x!\n", skb->protocol);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	css = skb_transport_offset(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	i = tx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	context_desc->lower_setup.ip_config = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	context_desc->upper_setup.tcp_fields.tucss = css;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	context_desc->upper_setup.tcp_fields.tucso =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		css + skb->csum_offset;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	context_desc->upper_setup.tcp_fields.tucse = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	context_desc->tcp_seg_setup.data = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	buffer_info->time_stamp = jiffies;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	buffer_info->next_to_watch = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	if (unlikely(++i == tx_ring->count)) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	tx_ring->next_to_use = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	return true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
#define E1000_MAX_TXD_PWR	12
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
static int e1000_tx_map(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			struct e1000_tx_ring *tx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			struct sk_buff *skb, unsigned int first,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
			unsigned int max_per_txd, unsigned int nr_frags,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
			unsigned int mss)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	unsigned int len = skb_headlen(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	unsigned int offset = 0, size, count = 0, i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	unsigned int f;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	i = tx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	while (len) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
		buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		size = min(len, max_per_txd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		/* Workaround for Controller erratum --
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		 * descriptor for non-tso packet in a linear SKB that follows a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		 * tso gets written back prematurely before the data is fully
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		 * DMA'd to the controller */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		if (!skb->data_len && tx_ring->last_tx_tso &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		    !skb_is_gso(skb)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			tx_ring->last_tx_tso = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			size -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		/* Workaround for premature desc write-backs
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		 * in TSO mode.  Append 4-byte sentinel desc */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		if (unlikely(mss && !nr_frags && size == len && size > 8))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
			size -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		/* work-around for errata 10 and it applies
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		 * to all controllers in PCI-X mode
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		 * The fix is to make sure that the first descriptor of a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		                (size > 2015) && count == 0))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		        size = 2015;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		 * terminating buffers within evenly-aligned dwords. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		if (unlikely(adapter->pcix_82544 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		   size > 4))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			size -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		buffer_info->length = size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		/* set time_stamp *before* dma to help avoid a possible race */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
		buffer_info->time_stamp = jiffies;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		buffer_info->mapped_as_page = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		buffer_info->dma = dma_map_single(&pdev->dev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
						  skb->data + offset,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
						  size,	DMA_TO_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
			goto dma_error;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		buffer_info->next_to_watch = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		len -= size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		offset += size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
		count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		if (len) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			i++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
			if (unlikely(i == tx_ring->count))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
				i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	for (f = 0; f < nr_frags; f++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		struct skb_frag_struct *frag;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		frag = &skb_shinfo(skb)->frags[f];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		len = frag->size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
		offset = frag->page_offset;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		while (len) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
			i++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
			if (unlikely(i == tx_ring->count))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
				i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
			buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
			size = min(len, max_per_txd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			/* Workaround for premature desc write-backs
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
			 * in TSO mode.  Append 4-byte sentinel desc */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
				size -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
			/* Workaround for potential 82544 hang in PCI-X.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
			 * Avoid terminating buffers within evenly-aligned
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
			 * dwords. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			if (unlikely(adapter->pcix_82544 &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			    !((unsigned long)(page_to_phys(frag->page) + offset
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			                      + size - 1) & 4) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			    size > 4))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
				size -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
			buffer_info->length = size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
			buffer_info->time_stamp = jiffies;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
			buffer_info->mapped_as_page = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
							offset,	size,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
							DMA_TO_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
				goto dma_error;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
			buffer_info->next_to_watch = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
			len -= size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
			offset += size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
			count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	tx_ring->buffer_info[i].skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	tx_ring->buffer_info[first].next_to_watch = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	return count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
dma_error:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	dev_err(&pdev->dev, "TX DMA map failed\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	if (count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		count--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	while (count--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		if (i==0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			i += tx_ring->count;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		i--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
static void e1000_tx_queue(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
			   struct e1000_tx_ring *tx_ring, int tx_flags,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
			   int count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	struct e1000_tx_desc *tx_desc = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		             E1000_TXD_CMD_TSE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		txd_lower |= E1000_TXD_CMD_VLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	i = tx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	while (count--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		tx_desc = E1000_TX_DESC(*tx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		tx_desc->lower.data =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
			cpu_to_le32(txd_lower | buffer_info->length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		tx_desc->upper.data = cpu_to_le32(txd_upper);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		if (unlikely(++i == tx_ring->count)) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	/* Force memory writes to complete before letting h/w
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	 * know there are new descriptors to fetch.  (Only
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	 * applicable for weak-ordered memory model archs,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	 * such as IA-64). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	wmb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	tx_ring->next_to_use = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	writel(i, hw->hw_addr + tx_ring->tdt);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	/* we need this if more than one processor can write to our tail
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	 * at a time, it syncronizes IO on IA64/Altix systems */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	mmiowb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 * 82547 workaround to avoid controller hang in half-duplex environment.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 * The workaround is to avoid queuing a large packet that would span
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
 * the internal Tx FIFO ring boundary by notifying the stack to resend
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
 * to the beginning of the Tx FIFO.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
#define E1000_FIFO_HDR			0x10
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
#define E1000_82547_PAD_LEN		0x3E0
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
				       struct sk_buff *skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	if (adapter->link_duplex != HALF_DUPLEX)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		goto no_fifo_stall_required;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	if (atomic_read(&adapter->tx_fifo_stall))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		return 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		atomic_set(&adapter->tx_fifo_stall, 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
		return 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
no_fifo_stall_required:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	adapter->tx_fifo_head += skb_fifo_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	netif_stop_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	/* Herbert's original patch had:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	 *  smp_mb__after_netif_stop_queue();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	 * but since that doesn't exist yet, just open code it. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	smp_mb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	/* We need to check again in a case another CPU has just
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	 * made room available. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		return -EBUSY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	/* A reprieve! */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	netif_start_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	++adapter->restart_queue;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
static int e1000_maybe_stop_tx(struct net_device *netdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
                               struct e1000_tx_ring *tx_ring, int size)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	return __e1000_maybe_stop_tx(netdev, size);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
				    struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	struct e1000_tx_ring *tx_ring;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	unsigned int tx_flags = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	unsigned int len = skb_headlen(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	unsigned int nr_frags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	unsigned int mss;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	int count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	int tso;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	unsigned int f;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	/* This goes back to the question of how to logically map a tx queue
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	 * to a flow.  Right now, performance is impacted slightly negatively
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	 * if using multiple tx queues.  If the stack breaks away from a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	 * single qdisc implementation, we can look at this again. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	tx_ring = adapter->tx_ring;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	if (unlikely(skb->len <= 0)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		dev_kfree_skb_any(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		return NETDEV_TX_OK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	mss = skb_shinfo(skb)->gso_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
	/* The controller does a simple calculation to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	 * make sure there is enough room in the FIFO before
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	 * initiating the DMA for each buffer.  The calc is:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	 * 4 = ceil(buffer len/mss).  To make sure we don't
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	 * overrun the FIFO, adjust the max buffer len if mss
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	 * drops. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	if (mss) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		u8 hdr_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		max_per_txd = min(mss << 2, max_per_txd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
		max_txd_pwr = fls(max_per_txd) - 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		if (skb->data_len && hdr_len == len) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
			switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
				unsigned int pull_size;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			case e1000_82544:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
				/* Make sure we have room to chop off 4 bytes,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
				 * and that the end alignment will work out to
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
				 * this hardware's requirements
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
				 * NOTE: this is a TSO only workaround
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
				 * if end byte alignment not correct move us
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
				 * into the next dword */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
					break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
				/* fall through */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
				pull_size = min((unsigned int)4, skb->data_len);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
				if (!__pskb_pull_tail(skb, pull_size)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
					e_err("__pskb_pull_tail failed.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
					dev_kfree_skb_any(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
					return NETDEV_TX_OK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
				len = skb_headlen(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
			default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
				/* do nothing */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	/* reserve a descriptor for the offload context */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	/* Controller Erratum workaround */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	count += TXD_USE_COUNT(len, max_txd_pwr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	if (adapter->pcix_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	/* work-around for errata 10 and it applies to all controllers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	 * in PCI-X mode, so add one more descriptor to the count
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			(len > 2015)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	nr_frags = skb_shinfo(skb)->nr_frags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	for (f = 0; f < nr_frags; f++)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
				       max_txd_pwr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	if (adapter->pcix_82544)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		count += nr_frags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	/* need: count + 2 desc gap to keep tail from touching
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	 * head, otherwise try next time */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		return NETDEV_TX_BUSY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	if (unlikely(hw->mac_type == e1000_82547)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
			netif_stop_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
				mod_timer(&adapter->tx_fifo_stall_timer,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
				          jiffies + 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			return NETDEV_TX_BUSY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		tx_flags |= E1000_TX_FLAGS_VLAN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	first = tx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	tso = e1000_tso(adapter, tx_ring, skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	if (tso < 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		dev_kfree_skb_any(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		return NETDEV_TX_OK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	if (likely(tso)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		if (likely(hw->mac_type != e1000_82544))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
			tx_ring->last_tx_tso = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		tx_flags |= E1000_TX_FLAGS_TSO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		tx_flags |= E1000_TX_FLAGS_CSUM;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	if (likely(skb->protocol == htons(ETH_P_IP)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		tx_flags |= E1000_TX_FLAGS_IPV4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	                     nr_frags, mss);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	if (count) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		/* Make sure there is space in the ring for the next send. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		dev_kfree_skb_any(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		tx_ring->buffer_info[first].time_stamp = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		tx_ring->next_to_use = first;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	return NETDEV_TX_OK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
 * e1000_tx_timeout - Respond to a Tx Hang
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
static void e1000_tx_timeout(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	/* Do the reset outside of interrupt context */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	adapter->tx_timeout_count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	schedule_work(&adapter->reset_task);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
static void e1000_reset_task(struct work_struct *work)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	struct e1000_adapter *adapter =
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		container_of(work, struct e1000_adapter, reset_task);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	e1000_reinit_locked(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 * e1000_get_stats - Get System Network Statistics
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
 * Returns the address of the device statistics structure.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
 * The statistics are actually updated from the timer callback.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	/* only return the current stats */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	return &netdev->stats;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 * e1000_change_mtu - Change the Maximum Transfer Unit
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
 * @netdev: network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
 * @new_mtu: new value for maximum frame size
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
 * Returns 0 on success, negative on failure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		e_err("Invalid MTU setting\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		return -EINVAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	/* Adapter-specific max frame size limits. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	switch (hw->mac_type) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
	case e1000_undefined ... e1000_82542_rev2_1:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
			e_err("Jumbo Frames not supported.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
			return -EINVAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		msleep(1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	/* e1000_down has a dependency on max_frame_size */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	hw->max_frame_size = max_frame;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		e1000_down(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	 * means we reserve 2 more, this pushes us to allocate from the next
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	 * larger slab size.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	 * i.e. RXBUFFER_2048 --> size-4096 slab
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	 *  fragmented skbs */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	if (max_frame <= E1000_RXBUFFER_2048)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
		adapter->rx_buffer_len = PAGE_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	/* adjust allocation if LPE protects us, and we aren't using SBP */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	if (!hw->tbi_compatibility_on &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	pr_info("%s changing MTU from %d to %d\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		netdev->name, netdev->mtu, new_mtu);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	netdev->mtu = new_mtu;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		e1000_up(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
		e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	clear_bit(__E1000_RESETTING, &adapter->flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
 * e1000_update_stats - Update the board statistics counters
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
void e1000_update_stats(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	unsigned long flags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	u16 phy_tmp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	 * Prevent stats update while adapter is being reset, or if the pci
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	 * connection is down.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	if (adapter->link_speed == 0)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	if (pci_channel_offline(pdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	spin_lock_irqsave(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	/* these counters are modified from e1000_tbi_adjust_stats,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	 * called from the interrupt context, so they must only
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	 * be written while holding adapter->stats_lock
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	adapter->stats.crcerrs += er32(CRCERRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	adapter->stats.gprc += er32(GPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	adapter->stats.gorcl += er32(GORCL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	adapter->stats.gorch += er32(GORCH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	adapter->stats.bprc += er32(BPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	adapter->stats.mprc += er32(MPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	adapter->stats.roc += er32(ROC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	adapter->stats.prc64 += er32(PRC64);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	adapter->stats.prc127 += er32(PRC127);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	adapter->stats.prc255 += er32(PRC255);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	adapter->stats.prc511 += er32(PRC511);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	adapter->stats.prc1023 += er32(PRC1023);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	adapter->stats.prc1522 += er32(PRC1522);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	adapter->stats.symerrs += er32(SYMERRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	adapter->stats.mpc += er32(MPC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	adapter->stats.scc += er32(SCC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	adapter->stats.ecol += er32(ECOL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	adapter->stats.mcc += er32(MCC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	adapter->stats.latecol += er32(LATECOL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	adapter->stats.dc += er32(DC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	adapter->stats.sec += er32(SEC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	adapter->stats.rlec += er32(RLEC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	adapter->stats.xonrxc += er32(XONRXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	adapter->stats.xontxc += er32(XONTXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	adapter->stats.xoffrxc += er32(XOFFRXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	adapter->stats.xofftxc += er32(XOFFTXC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	adapter->stats.fcruc += er32(FCRUC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	adapter->stats.gptc += er32(GPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	adapter->stats.gotcl += er32(GOTCL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
	adapter->stats.gotch += er32(GOTCH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	adapter->stats.rnbc += er32(RNBC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	adapter->stats.ruc += er32(RUC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	adapter->stats.rfc += er32(RFC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	adapter->stats.rjc += er32(RJC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	adapter->stats.torl += er32(TORL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	adapter->stats.torh += er32(TORH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	adapter->stats.totl += er32(TOTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	adapter->stats.toth += er32(TOTH);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	adapter->stats.tpr += er32(TPR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	adapter->stats.ptc64 += er32(PTC64);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	adapter->stats.ptc127 += er32(PTC127);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	adapter->stats.ptc255 += er32(PTC255);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	adapter->stats.ptc511 += er32(PTC511);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	adapter->stats.ptc1023 += er32(PTC1023);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	adapter->stats.ptc1522 += er32(PTC1522);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	adapter->stats.mptc += er32(MPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	adapter->stats.bptc += er32(BPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	/* used for adaptive IFS */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	hw->tx_packet_delta = er32(TPT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	adapter->stats.tpt += hw->tx_packet_delta;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	hw->collision_delta = er32(COLC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	adapter->stats.colc += hw->collision_delta;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	if (hw->mac_type >= e1000_82543) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		adapter->stats.algnerrc += er32(ALGNERRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
		adapter->stats.rxerrc += er32(RXERRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
		adapter->stats.tncrs += er32(TNCRS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
		adapter->stats.cexterr += er32(CEXTERR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		adapter->stats.tsctc += er32(TSCTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		adapter->stats.tsctfc += er32(TSCTFC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	/* Fill out the OS statistics structure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	netdev->stats.multicast = adapter->stats.mprc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	netdev->stats.collisions = adapter->stats.colc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	/* Rx Errors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	/* RLEC on some newer hardware can be incorrect so build
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	* our own version based on RUC and ROC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	netdev->stats.rx_errors = adapter->stats.rxerrc +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		adapter->stats.crcerrs + adapter->stats.algnerrc +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		adapter->stats.ruc + adapter->stats.roc +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		adapter->stats.cexterr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	/* Tx Errors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	netdev->stats.tx_errors = adapter->stats.txerrc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	netdev->stats.tx_window_errors = adapter->stats.latecol;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	if (hw->bad_tx_carr_stats_fd &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	    adapter->link_duplex == FULL_DUPLEX) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		netdev->stats.tx_carrier_errors = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		adapter->stats.tncrs = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	/* Tx Dropped needs to be maintained elsewhere */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	/* Phy Stats */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		if ((adapter->link_speed == SPEED_1000) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
			adapter->phy_stats.idle_errors += phy_tmp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		if ((hw->mac_type <= e1000_82546) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		   (hw->phy_type == e1000_phy_m88) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
			adapter->phy_stats.receive_errors += phy_tmp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	/* Management Stats */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	if (hw->has_smbus) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
		adapter->stats.mgptc += er32(MGTPTC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		adapter->stats.mgprc += er32(MGTPRC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		adapter->stats.mgpdc += er32(MGTPDC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
 * e1000_intr - Interrupt Handler
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
 * @irq: interrupt number
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
 * @data: pointer to a network interface device structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
static irqreturn_t e1000_intr(int irq, void *data)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	struct net_device *netdev = data;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	u32 icr = er32(ICR);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		return IRQ_NONE;  /* Not our interrupt */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		hw->get_link_status = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		/* guard against interrupt when we're going down */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
		if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	/* disable interrupts, without the synchronize_irq bit */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	ew32(IMC, ~0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	E1000_WRITE_FLUSH();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	if (likely(napi_schedule_prep(&adapter->napi))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		adapter->total_tx_bytes = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		adapter->total_tx_packets = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		adapter->total_rx_bytes = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		adapter->total_rx_packets = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		__napi_schedule(&adapter->napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		/* this really should not happen! if it does it is basically a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		 * bug, but not a hard error, so enable ints and continue */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
			e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	return IRQ_HANDLED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
 * e1000_clean - NAPI Rx polling callback
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
static int e1000_clean(struct napi_struct *napi, int budget)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	int tx_clean_complete = 0, work_done = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	if (!tx_clean_complete)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		work_done = budget;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	/* If budget not fully consumed, exit the polling mode */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	if (work_done < budget) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		if (likely(adapter->itr_setting & 3))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
			e1000_set_itr(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		napi_complete(napi);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
		if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
			e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	return work_done;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
			       struct e1000_tx_ring *tx_ring)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	struct e1000_tx_desc *tx_desc, *eop_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	unsigned int i, eop;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	unsigned int count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	unsigned int total_tx_bytes=0, total_tx_packets=0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	i = tx_ring->next_to_clean;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	eop = tx_ring->buffer_info[i].next_to_watch;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	       (count < tx_ring->count)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		bool cleaned = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		rmb();	/* read buffer_info after eop_desc */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		for ( ; !cleaned; count++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
			tx_desc = E1000_TX_DESC(*tx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
			buffer_info = &tx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			cleaned = (i == eop);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
			if (cleaned) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
				struct sk_buff *skb = buffer_info->skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
				unsigned int segs, bytecount;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
				segs = skb_shinfo(skb)->gso_segs ?: 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
				/* multiply data chunks by size of headers */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
				bytecount = ((segs - 1) * skb_headlen(skb)) +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
				            skb->len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
				total_tx_packets += segs;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
				total_tx_bytes += bytecount;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
			tx_desc->upper.data = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
			if (unlikely(++i == tx_ring->count)) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
		eop = tx_ring->buffer_info[i].next_to_watch;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	tx_ring->next_to_clean = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
#define TX_WAKE_THRESHOLD 32
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	if (unlikely(count && netif_carrier_ok(netdev) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		/* Make sure that anybody stopping the queue after this
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
		 * sees the new next_to_clean.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
		smp_mb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
		if (netif_queue_stopped(netdev) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
			netif_wake_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
			++adapter->restart_queue;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	if (adapter->detect_tx_hung) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
		/* Detect a transmit hang in hardware, this serializes the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		 * check with the clearing of time_stamp and movement of i */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		adapter->detect_tx_hung = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		if (tx_ring->buffer_info[eop].time_stamp &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
		               (adapter->tx_timeout_factor * HZ)) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
			/* detected Tx unit hang */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			e_err("Detected Tx Unit Hang\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
			      "  Tx Queue             <%lu>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			      "  TDH                  <%x>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
			      "  TDT                  <%x>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
			      "  next_to_use          <%x>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
			      "  next_to_clean        <%x>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
			      "buffer_info[next_to_clean]\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
			      "  time_stamp           <%lx>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
			      "  next_to_watch        <%x>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
			      "  jiffies              <%lx>\n"
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
			      "  next_to_watch.status <%x>\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
				(unsigned long)((tx_ring - adapter->tx_ring) /
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
					sizeof(struct e1000_tx_ring)),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
				readl(hw->hw_addr + tx_ring->tdh),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
				readl(hw->hw_addr + tx_ring->tdt),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
				tx_ring->next_to_use,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
				tx_ring->next_to_clean,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
				tx_ring->buffer_info[eop].time_stamp,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
				eop,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
				jiffies,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
				eop_desc->upper.fields.status);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
			netif_stop_queue(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	adapter->total_tx_bytes += total_tx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	adapter->total_tx_packets += total_tx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	netdev->stats.tx_bytes += total_tx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	netdev->stats.tx_packets += total_tx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	return (count < tx_ring->count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
 * e1000_rx_checksum - Receive Checksum Offload for 82543
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
 * @adapter:     board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
 * @status_err:  receive descriptor status and error fields
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
 * @csum:        receive descriptor csum field
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
 * @sk_buff:     socket buffer with received data
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
			      u32 csum, struct sk_buff *skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	u16 status = (u16)status_err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
	u8 errors = (u8)(status_err >> 24);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	skb->ip_summed = CHECKSUM_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	/* 82543 or newer only */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	if (unlikely(hw->mac_type < e1000_82543)) return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
	/* Ignore Checksum bit is set */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	/* TCP/UDP checksum error bit is set */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		/* let the stack verify checksum errors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		adapter->hw_csum_err++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	/* TCP/UDP Checksum has not been calculated */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	if (!(status & E1000_RXD_STAT_TCPCS))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* It must be a TCP or UDP packet with a valid checksum */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		/* TCP checksum is good */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		skb->ip_summed = CHECKSUM_UNNECESSARY;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	adapter->hw_csum_good++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
 * e1000_consume_page - helper function
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
                               u16 length)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	bi->page = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	skb->len += length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	skb->data_len += length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	skb->truesize += length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
 * e1000_receive_skb - helper function to handle rx indications
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
 * @status: descriptor status field as written by hardware
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
 * @skb: pointer to sk_buff to be indicated to stack
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
			      __le16 vlan, struct sk_buff *skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		                         le16_to_cpu(vlan) &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		                         E1000_RXD_SPC_VLAN_MASK);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		netif_receive_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
 * @rx_ring: ring to clean
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
 * @work_done: amount of napi work completed this call
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
 * @work_to_do: max amount of work allowed for this call to do
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
 * the return value indicates whether actual cleaning was done, there
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
 * is no guarantee that everything was cleaned
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
				     struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
				     int *work_done, int work_to_do)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
	struct e1000_rx_desc *rx_desc, *next_rxd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	struct e1000_buffer *buffer_info, *next_buffer;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	unsigned long irq_flags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	u32 length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	int cleaned_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	bool cleaned = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	unsigned int total_rx_bytes=0, total_rx_packets=0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	i = rx_ring->next_to_clean;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	rx_desc = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	while (rx_desc->status & E1000_RXD_STAT_DD) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
		struct sk_buff *skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		u8 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		if (*work_done >= work_to_do)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		(*work_done)++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
		rmb(); /* read descriptor and rx_buffer_info after status DD */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
		status = rx_desc->status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		skb = buffer_info->skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		if (++i == rx_ring->count) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		next_rxd = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		prefetch(next_rxd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		next_buffer = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
		cleaned = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		cleaned_count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		dma_unmap_page(&pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
			       buffer_info->length, DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
		length = le16_to_cpu(rx_desc->length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		/* errors is only valid for DD + EOP descriptors */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
			u8 last_byte = *(skb->data + length - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
				       last_byte)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
				spin_lock_irqsave(&adapter->stats_lock,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
				                  irq_flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
				e1000_tbi_adjust_stats(hw, &adapter->stats,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
				                       length, skb->data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
				spin_unlock_irqrestore(&adapter->stats_lock,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
				                       irq_flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
				length--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
				/* recycle both page and skb */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
				buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
				/* an error means any chain goes out the window
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
				 * too */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
				if (rx_ring->rx_skb_top)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
					dev_kfree_skb(rx_ring->rx_skb_top);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
				rx_ring->rx_skb_top = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
				goto next_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
#define rxtop rx_ring->rx_skb_top
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
		if (!(status & E1000_RXD_STAT_EOP)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
			/* this descriptor is only the beginning (or middle) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
			if (!rxtop) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
				/* this is the beginning of a chain */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
				rxtop = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
				                   0, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
				/* this is the middle of a chain */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
				skb_fill_page_desc(rxtop,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
				    skb_shinfo(rxtop)->nr_frags,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
				    buffer_info->page, 0, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
				/* re-use the skb, only consumed the page */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
				buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
			e1000_consume_page(buffer_info, rxtop, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			goto next_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
			if (rxtop) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
				/* end of the chain */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
				skb_fill_page_desc(rxtop,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
				    skb_shinfo(rxtop)->nr_frags,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
				    buffer_info->page, 0, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
				/* re-use the current skb, we only consumed the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
				 * page */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
				buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
				skb = rxtop;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
				rxtop = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
				e1000_consume_page(buffer_info, skb, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
				/* no chain, got EOP, this buf is the packet
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
				 * copybreak to save the put_page/alloc_page */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
				if (length <= copybreak &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
				    skb_tailroom(skb) >= length) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
					u8 *vaddr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
					vaddr = kmap_atomic(buffer_info->page,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
					                    KM_SKB_DATA_SOFTIRQ);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
					memcpy(skb_tail_pointer(skb), vaddr, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
					kunmap_atomic(vaddr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
					              KM_SKB_DATA_SOFTIRQ);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
					/* re-use the page, so don't erase
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
					 * buffer_info->page */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
					skb_put(skb, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
				} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
					skb_fill_page_desc(skb, 0,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
					                   buffer_info->page, 0,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
				                           length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
					e1000_consume_page(buffer_info, skb,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
					                   length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		e1000_rx_checksum(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		                  (u32)(status) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		                  ((u32)(rx_desc->errors) << 24),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		                  le16_to_cpu(rx_desc->csum), skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		pskb_trim(skb, skb->len - 4);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		/* probably a little skewed due to removing CRC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		total_rx_bytes += skb->len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		total_rx_packets++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		/* eth type trans needs skb->data to point to something */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		if (!pskb_may_pull(skb, ETH_HLEN)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
			e_err("pskb_may_pull failed.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
			dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
			goto next_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		skb->protocol = eth_type_trans(skb, netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
next_desc:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		rx_desc->status = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		/* return some buffers to hardware, one at a time is too slow */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
			cleaned_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		/* use prefetched values */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		rx_desc = next_rxd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
		buffer_info = next_buffer;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	rx_ring->next_to_clean = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	if (cleaned_count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	adapter->total_rx_packets += total_rx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	adapter->total_rx_bytes += total_rx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	netdev->stats.rx_bytes += total_rx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	netdev->stats.rx_packets += total_rx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	return cleaned;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
 * this should improve performance for small packets with large amounts
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
 * of reassembly being done in the stack
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
static void e1000_check_copybreak(struct net_device *netdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
				 struct e1000_buffer *buffer_info,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
				 u32 length, struct sk_buff **skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	struct sk_buff *new_skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	if (length > copybreak)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	if (!new_skb)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
				       (*skb)->data - NET_IP_ALIGN,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
				       length + NET_IP_ALIGN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	/* save the skb in buffer_info as good */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	buffer_info->skb = *skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	*skb = new_skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
 * @adapter: board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
 * @rx_ring: ring to clean
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
 * @work_done: amount of napi work completed this call
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
 * @work_to_do: max amount of work allowed for this call to do
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
			       struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
			       int *work_done, int work_to_do)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	struct e1000_rx_desc *rx_desc, *next_rxd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	struct e1000_buffer *buffer_info, *next_buffer;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	unsigned long flags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	u32 length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	int cleaned_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	bool cleaned = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	unsigned int total_rx_bytes=0, total_rx_packets=0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	i = rx_ring->next_to_clean;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	rx_desc = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	while (rx_desc->status & E1000_RXD_STAT_DD) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		struct sk_buff *skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		u8 status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		if (*work_done >= work_to_do)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		(*work_done)++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		rmb(); /* read descriptor and rx_buffer_info after status DD */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		status = rx_desc->status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		skb = buffer_info->skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		prefetch(skb->data - NET_IP_ALIGN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		if (++i == rx_ring->count) i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		next_rxd = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		prefetch(next_rxd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		next_buffer = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
		cleaned = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
		cleaned_count++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		dma_unmap_single(&pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
				 buffer_info->length, DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
		length = le16_to_cpu(rx_desc->length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		/* !EOP means multiple descriptors were used to store a single
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		 * packet, if thats the case we need to toss it.  In fact, we
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
		 * to toss every packet with the EOP bit clear and the next
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		 * frame that _does_ have the EOP bit set, as it is by
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		 * definition only a frame fragment
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
			adapter->discarding = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		if (adapter->discarding) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
			/* All receives must fit into a single buffer */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
			e_info("Receive packet consumed multiple buffers\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
			/* recycle */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
			buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
			if (status & E1000_RXD_STAT_EOP)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
				adapter->discarding = false;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
			goto next_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
			u8 last_byte = *(skb->data + length - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
				       last_byte)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
				spin_lock_irqsave(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
				e1000_tbi_adjust_stats(hw, &adapter->stats,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
				                       length, skb->data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
				spin_unlock_irqrestore(&adapter->stats_lock,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
				                       flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
				length--;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
				/* recycle */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
				buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
				goto next_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		/* adjust length to remove Ethernet CRC, this must be
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
		 * done after the TBI_ACCEPT workaround above */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		length -= 4;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		/* probably a little skewed due to removing CRC */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		total_rx_bytes += length;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		total_rx_packets++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		skb_put(skb, length);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		/* Receive Checksum Offload */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		e1000_rx_checksum(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
				  (u32)(status) |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
				  ((u32)(rx_desc->errors) << 24),
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
				  le16_to_cpu(rx_desc->csum), skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		skb->protocol = eth_type_trans(skb, netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		e1000_receive_skb(adapter, status, rx_desc->special, skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
next_desc:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		rx_desc->status = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		/* return some buffers to hardware, one at a time is too slow */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
			cleaned_count = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		/* use prefetched values */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		rx_desc = next_rxd;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
		buffer_info = next_buffer;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	rx_ring->next_to_clean = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	if (cleaned_count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	adapter->total_rx_packets += total_rx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	adapter->total_rx_bytes += total_rx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	netdev->stats.rx_bytes += total_rx_bytes;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	netdev->stats.rx_packets += total_rx_packets;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	return cleaned;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
 * @adapter: address of board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
 * @rx_ring: pointer to receive ring structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
 * @cleaned_count: number of buffers to allocate this pass
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
static void
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	struct e1000_rx_desc *rx_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	struct sk_buff *skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	i = rx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	while (cleaned_count--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		skb = buffer_info->skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		if (skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
			skb_trim(skb, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
			goto check_page;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		if (unlikely(!skb)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			/* Better luck next round */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
		/* Fix for errata 23, can't cross 64kB boundary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
			struct sk_buff *oldskb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
			e_err("skb align check failed: %u bytes at %p\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
			      bufsz, skb->data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			/* Try again, without freeing the previous */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
			/* Failed allocation, critical failure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
			if (!skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
				dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
				adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
				/* give up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
				dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
				dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
				break; /* while (cleaned_count--) */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			/* Use new allocation */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
			dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		buffer_info->length = adapter->rx_buffer_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
check_page:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		/* allocate a new page if necessary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		if (!buffer_info->page) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
			buffer_info->page = alloc_page(GFP_ATOMIC);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
			if (unlikely(!buffer_info->page)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
				adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		if (!buffer_info->dma) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
			buffer_info->dma = dma_map_page(&pdev->dev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
			                                buffer_info->page, 0,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
							buffer_info->length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
							DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
				put_page(buffer_info->page);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
				dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
				buffer_info->page = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
				buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
				buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
				adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
				break; /* while !buffer_info->skb */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		rx_desc = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		if (unlikely(++i == rx_ring->count))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
			i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	if (likely(rx_ring->next_to_use != i)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
		rx_ring->next_to_use = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		if (unlikely(i-- == 0))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
			i = (rx_ring->count - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
		/* Force memory writes to complete before letting h/w
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
		 * know there are new descriptors to fetch.  (Only
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		 * applicable for weak-ordered memory model archs,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
		 * such as IA-64). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		wmb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
 * @adapter: address of board private structure
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
				   struct e1000_rx_ring *rx_ring,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
				   int cleaned_count)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	struct net_device *netdev = adapter->netdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	struct pci_dev *pdev = adapter->pdev;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	struct e1000_rx_desc *rx_desc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	struct e1000_buffer *buffer_info;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	struct sk_buff *skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	unsigned int i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	unsigned int bufsz = adapter->rx_buffer_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	i = rx_ring->next_to_use;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
	buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	while (cleaned_count--) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
		skb = buffer_info->skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
		if (skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
			skb_trim(skb, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
			goto map_skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		if (unlikely(!skb)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
			/* Better luck next round */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
			adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
			break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		/* Fix for errata 23, can't cross 64kB boundary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			struct sk_buff *oldskb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			e_err("skb align check failed: %u bytes at %p\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
			      bufsz, skb->data);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
			/* Try again, without freeing the previous */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
			/* Failed allocation, critical failure */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
			if (!skb) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
				adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
				/* give up */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
				dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
				dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
				adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
				break; /* while !buffer_info->skb */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
			/* Use new allocation */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
			dev_kfree_skb(oldskb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
		buffer_info->skb = skb;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		buffer_info->length = adapter->rx_buffer_len;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
map_skb:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		buffer_info->dma = dma_map_single(&pdev->dev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
						  skb->data,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
						  buffer_info->length,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
						  DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
			dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
			buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
			adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
			break; /* while !buffer_info->skb */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		 * XXX if it was allocated cleanly it will never map to a
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		 * boundary crossing
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
		/* Fix for errata 23, can't cross 64kB boundary */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		if (!e1000_check_64k_bound(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
					(void *)(unsigned long)buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
					adapter->rx_buffer_len)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
			e_err("dma align check failed: %u bytes at %p\n",
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
			      adapter->rx_buffer_len,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			      (void *)(unsigned long)buffer_info->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
			dev_kfree_skb(skb);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
			buffer_info->skb = NULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
			dma_unmap_single(&pdev->dev, buffer_info->dma,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
					 adapter->rx_buffer_len,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
					 DMA_FROM_DEVICE);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			buffer_info->dma = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
			adapter->alloc_rx_buff_failed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			break; /* while !buffer_info->skb */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		rx_desc = E1000_RX_DESC(*rx_ring, i);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		if (unlikely(++i == rx_ring->count))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			i = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
		buffer_info = &rx_ring->buffer_info[i];
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	if (likely(rx_ring->next_to_use != i)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		rx_ring->next_to_use = i;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		if (unlikely(i-- == 0))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			i = (rx_ring->count - 1);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		/* Force memory writes to complete before letting h/w
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		 * know there are new descriptors to fetch.  (Only
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		 * applicable for weak-ordered memory model archs,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		 * such as IA-64). */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		wmb();
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		writel(i, hw->hw_addr + rx_ring->rdt);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
 * @adapter:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
static void e1000_smartspeed(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	u16 phy_status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	u16 phy_ctrl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
	if (adapter->smartspeed == 0) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		/* If Master/Slave config fault is asserted twice,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		 * we assume back-to-back */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
					    phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
			adapter->smartspeed++;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
			if (!e1000_phy_setup_autoneg(hw) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
			   !e1000_read_phy_reg(hw, PHY_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
				   	       &phy_ctrl)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
					     MII_CR_RESTART_AUTO_NEG);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
				e1000_write_phy_reg(hw, PHY_CTRL,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
						    phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
		/* If still no link, perhaps using 2/3 pair cable */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		phy_ctrl |= CR_1000T_MS_ENABLE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
		if (!e1000_phy_setup_autoneg(hw) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
				     MII_CR_RESTART_AUTO_NEG);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
		adapter->smartspeed = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
 * e1000_ioctl -
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
 * @netdev:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * @ifreq:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * @cmd:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	switch (cmd) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	case SIOCGMIIPHY:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	case SIOCGMIIREG:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
	case SIOCSMIIREG:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		return e1000_mii_ioctl(netdev, ifr, cmd);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		return -EOPNOTSUPP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
 * e1000_mii_ioctl -
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
 * @netdev:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
 * @ifreq:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
 * @cmd:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
 **/
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
			   int cmd)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	struct mii_ioctl_data *data = if_mii(ifr);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	int retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	u16 mii_reg;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	u16 spddplx;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	unsigned long flags;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	if (hw->media_type != e1000_media_type_copper)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		return -EOPNOTSUPP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	switch (cmd) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	case SIOCGMIIPHY:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		data->phy_id = hw->phy_addr;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
	case SIOCGMIIREG:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		spin_lock_irqsave(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
				   &data->val_out)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
			return -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	case SIOCSMIIREG:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		if (data->reg_num & ~(0x1F))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
			return -EFAULT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		mii_reg = data->val_in;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		spin_lock_irqsave(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
		if (e1000_write_phy_reg(hw, data->reg_num,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
					mii_reg)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			return -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		if (hw->media_type == e1000_media_type_copper) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
			switch (data->reg_num) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
			case PHY_CTRL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
				if (mii_reg & MII_CR_POWER_DOWN)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
					break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
					hw->autoneg = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
					hw->autoneg_advertised = 0x2F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
				} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
					if (mii_reg & 0x40)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
						spddplx = SPEED_1000;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
					else if (mii_reg & 0x2000)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
						spddplx = SPEED_100;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
					else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
						spddplx = SPEED_10;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
					spddplx += (mii_reg & 0x100)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
						   ? DUPLEX_FULL :
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
						   DUPLEX_HALF;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
					retval = e1000_set_spd_dplx(adapter,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
								    spddplx);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
					if (retval)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
						return retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
				}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
				if (netif_running(adapter->netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
					e1000_reinit_locked(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
				else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
					e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
			case M88E1000_PHY_SPEC_CTRL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
			case M88E1000_EXT_PHY_SPEC_CTRL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
				if (e1000_phy_reset(hw))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
					return -EIO;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
			switch (data->reg_num) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			case PHY_CTRL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
				if (mii_reg & MII_CR_POWER_DOWN)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
					break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
				if (netif_running(adapter->netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
					e1000_reinit_locked(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
				else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
					e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
				break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
			}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		return -EOPNOTSUPP;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	return E1000_SUCCESS;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
void e1000_pci_set_mwi(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	struct e1000_adapter *adapter = hw->back;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	int ret_val = pci_set_mwi(adapter->pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	if (ret_val)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		e_err("Error in setting MWI\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
void e1000_pci_clear_mwi(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	struct e1000_adapter *adapter = hw->back;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	pci_clear_mwi(adapter->pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	struct e1000_adapter *adapter = hw->back;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
	return pcix_get_mmrbc(adapter->pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	struct e1000_adapter *adapter = hw->back;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	pcix_set_mmrbc(adapter->pdev, mmrbc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	outl(value, port);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
static void e1000_vlan_rx_register(struct net_device *netdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
				   struct vlan_group *grp)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	u32 ctrl, rctl;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
		e1000_irq_disable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	adapter->vlgrp = grp;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	if (grp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		/* enable VLAN tag insert/strip */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		ctrl |= E1000_CTRL_VME;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		/* enable VLAN receive filtering */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		rctl &= ~E1000_RCTL_CFIEN;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		if (!(netdev->flags & IFF_PROMISC))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
			rctl |= E1000_RCTL_VFE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
		ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		e1000_update_mng_vlan(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		/* disable VLAN tag insert/strip */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
		ctrl &= ~E1000_CTRL_VME;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
		ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
		/* disable VLAN receive filtering */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		rctl &= ~E1000_RCTL_VFE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	u32 vfta, index;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	if ((hw->mng_cookie.status &
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	    (vid == adapter->mng_vlan_id))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	/* add VID to filter table */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
	index = (vid >> 5) & 0x7F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	vfta |= (1 << (vid & 0x1F));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	e1000_write_vfta(hw, index, vfta);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	u32 vfta, index;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
		e1000_irq_disable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	if (!test_bit(__E1000_DOWN, &adapter->flags))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		e1000_irq_enable(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	/* remove VID from filter table */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	index = (vid >> 5) & 0x7F;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	vfta &= ~(1 << (vid & 0x1F));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	e1000_write_vfta(hw, index, vfta);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
static void e1000_restore_vlan(struct e1000_adapter *adapter)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
	if (adapter->vlgrp) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		u16 vid;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
			if (!vlan_group_get_device(adapter->vlgrp, vid))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
				continue;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	hw->autoneg = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	/* Fiber NICs only allow 1000 gbps Full duplex */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	if ((hw->media_type == e1000_media_type_fiber) &&
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		e_err("Unsupported Speed/Duplex configuration\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		return -EINVAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	switch (spddplx) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	case SPEED_10 + DUPLEX_HALF:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		hw->forced_speed_duplex = e1000_10_half;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	case SPEED_10 + DUPLEX_FULL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		hw->forced_speed_duplex = e1000_10_full;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	case SPEED_100 + DUPLEX_HALF:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		hw->forced_speed_duplex = e1000_100_half;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	case SPEED_100 + DUPLEX_FULL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		hw->forced_speed_duplex = e1000_100_full;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	case SPEED_1000 + DUPLEX_FULL:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		hw->autoneg = 1;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		break;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	default:
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		e_err("Unsupported Speed/Duplex configuration\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
		return -EINVAL;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	u32 ctrl, ctrl_ext, rctl, status;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	u32 wufc = adapter->wol;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
#ifdef CONFIG_PM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	int retval = 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	netif_device_detach(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	if (netif_running(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		e1000_down(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
#ifdef CONFIG_PM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	retval = pci_save_state(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	if (retval)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		return retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	status = er32(STATUS);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	if (status & E1000_STATUS_LU)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		wufc &= ~E1000_WUFC_LNKC;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	if (wufc) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		e1000_setup_rctl(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		e1000_set_rx_mode(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
		/* turn on all-multi mode if wake on multicast is enabled */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		if (wufc & E1000_WUFC_MC) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
			rctl = er32(RCTL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			rctl |= E1000_RCTL_MPE;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			ew32(RCTL, rctl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		if (hw->mac_type >= e1000_82540) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			ctrl = er32(CTRL);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			/* advertise wake from D3Cold */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			#define E1000_CTRL_ADVD3WUC 0x00100000
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
			/* phy power management enable */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
			ctrl |= E1000_CTRL_ADVD3WUC |
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
				E1000_CTRL_EN_PHY_PWR_MGMT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			ew32(CTRL, ctrl);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
		if (hw->media_type == e1000_media_type_fiber ||
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		    hw->media_type == e1000_media_type_internal_serdes) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			/* keep the laser running in D3 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
			ctrl_ext = er32(CTRL_EXT);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
			ew32(CTRL_EXT, ctrl_ext);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		ew32(WUC, E1000_WUC_PME_EN);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		ew32(WUFC, wufc);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		ew32(WUC, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		ew32(WUFC, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	e1000_release_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	*enable_wake = !!wufc;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	/* make sure adapter isn't asleep if manageability is enabled */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	if (adapter->en_mng_pt)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		*enable_wake = true;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		e1000_free_irq(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	pci_disable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
#ifdef CONFIG_PM
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	int retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	bool wake;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	retval = __e1000_shutdown(pdev, &wake);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	if (retval)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		return retval;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	if (wake) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
		pci_prepare_to_sleep(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	} else {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		pci_wake_from_d3(pdev, false);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
		pci_set_power_state(pdev, PCI_D3hot);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
static int e1000_resume(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	u32 err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	pci_set_power_state(pdev, PCI_D0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	pci_restore_state(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	pci_save_state(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	if (adapter->need_ioport)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		err = pci_enable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		err = pci_enable_device_mem(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		pr_err("Cannot enable PCI device from suspend\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	pci_set_master(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	pci_enable_wake(pdev, PCI_D3hot, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	pci_enable_wake(pdev, PCI_D3cold, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	if (netif_running(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
		err = e1000_request_irq(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		if (err)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			return err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	e1000_power_up_phy(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	ew32(WUS, ~0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	e1000_init_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		e1000_up(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	netif_device_attach(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	return 0;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
static void e1000_shutdown(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	bool wake;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	__e1000_shutdown(pdev, &wake);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	if (system_state == SYSTEM_POWER_OFF) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		pci_wake_from_d3(pdev, wake);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		pci_set_power_state(pdev, PCI_D3hot);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
#ifdef CONFIG_NET_POLL_CONTROLLER
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
/*
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
 * Polling 'interrupt' - used by things like netconsole to send skbs
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
 * without having to re-enable interrupts. It's not called while
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
 * the interrupt routine is executing.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
static void e1000_netpoll(struct net_device *netdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	disable_irq(adapter->pdev->irq);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	e1000_intr(adapter->pdev->irq, netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	enable_irq(adapter->pdev->irq);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
#endif
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
 * e1000_io_error_detected - called when PCI error is detected
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
 * @pdev: Pointer to PCI device
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
 * @state: The current pci connection state
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
 * This function is called after a PCI bus error affecting
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
 * this device has been detected.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
						pci_channel_state_t state)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	netif_device_detach(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	if (state == pci_channel_io_perm_failure)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
		return PCI_ERS_RESULT_DISCONNECT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	if (netif_running(netdev))
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		e1000_down(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	pci_disable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	/* Request a slot slot reset. */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	return PCI_ERS_RESULT_NEED_RESET;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
 * e1000_io_slot_reset - called after the pci bus has been reset.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
 * @pdev: Pointer to PCI device
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
 * Restart the card from scratch, as if from a cold-boot. Implementation
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
 * resembles the first-half of the e1000_resume routine.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	struct e1000_hw *hw = &adapter->hw;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	int err;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	if (adapter->need_ioport)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		err = pci_enable_device(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	else
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
		err = pci_enable_device_mem(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	if (err) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
		pr_err("Cannot re-enable PCI device after reset.\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
		return PCI_ERS_RESULT_DISCONNECT;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	pci_set_master(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	pci_enable_wake(pdev, PCI_D3hot, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	pci_enable_wake(pdev, PCI_D3cold, 0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	e1000_reset(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	ew32(WUS, ~0);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	return PCI_ERS_RESULT_RECOVERED;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
/**
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
 * e1000_io_resume - called when traffic can start flowing again.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
 * @pdev: Pointer to PCI device
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
 *
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
 * This callback is called when the error recovery driver tells us that
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
 * its OK to resume normal operation. Implementation resembles the
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
 * second-half of the e1000_resume routine.
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
 */
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
static void e1000_io_resume(struct pci_dev *pdev)
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
{
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	struct net_device *netdev = pci_get_drvdata(pdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	struct e1000_adapter *adapter = netdev_priv(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	e1000_init_manageability(adapter);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	if (netif_running(netdev)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		if (e1000_up(adapter)) {
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
			pr_info("can't bring device back up after reset\n");
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
			return;
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
		}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	netif_device_attach(netdev);
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
}
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
9c0710c38627 Added e1000 driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
/* e1000_main.c */