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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
  vim: noexpandtab
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000-2.6.32-ethercat.h"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <net/ip6_checksum.h>
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
char e1000_driver_name[] = "ec_e1000";
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#define DRV_VERSION "7.3.21-k5-NAPI"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
const char e1000_driver_version[] = DRV_VERSION;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
/* e1000_pci_tbl - PCI Device ID Table
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Last entry must be all 0s
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 * Macro expands to...
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
static struct pci_device_id e1000_pci_tbl[] = {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	/* required last entry */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	{0,}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
// do not auto-load driver
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
int e1000_up(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
void e1000_down(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
void e1000_reinit_locked(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
void e1000_reset(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
                             struct e1000_tx_ring *txdr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
                             struct e1000_rx_ring *rxdr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
                             struct e1000_tx_ring *tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
                             struct e1000_rx_ring *rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
void e1000_update_stats(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static int e1000_init_module(void);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static void e1000_exit_module(void);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static void __devexit e1000_remove(struct pci_dev *pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_alloc_queues(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static int e1000_sw_init(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static int e1000_open(struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static int e1000_close(struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_configure_tx(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_configure_rx(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_setup_rctl(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
                                struct e1000_tx_ring *tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
                                struct e1000_rx_ring *rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_set_rx_mode(struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static void e1000_update_phy_info(unsigned long data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_watchdog(unsigned long data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static void e1000_82547_tx_fifo_stall(unsigned long data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
				    struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static int e1000_set_mac(struct net_device *netdev, void *p);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
void ec_poll(struct net_device *);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static irqreturn_t e1000_intr(int irq, void *data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       struct e1000_tx_ring *tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static int e1000_clean(struct napi_struct *napi, int budget);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
			       struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
			       int *work_done, int work_to_do);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
				     struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
				     int *work_done, int work_to_do);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
				   struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
				   int cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
					 struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
					 int cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
			   int cmd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static void e1000_tx_timeout(struct net_device *dev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static void e1000_reset_task(struct work_struct *work);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_smartspeed(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
                                       struct sk_buff *skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static void e1000_restore_vlan(struct e1000_adapter *adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
#ifdef CONFIG_PM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static int e1000_resume(struct pci_dev *pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static void e1000_shutdown(struct pci_dev *pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
#ifdef CONFIG_NET_POLL_CONTROLLER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
/* for netdump / net console */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static void e1000_netpoll (struct net_device *netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
#define COPYBREAK_DEFAULT 256
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
module_param(copybreak, uint, 0644);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
MODULE_PARM_DESC(copybreak,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	"Maximum size of packet that is copied to a new buffer on receive");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
                     pci_channel_state_t state);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
static void e1000_io_resume(struct pci_dev *pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
static struct pci_error_handlers e1000_err_handler = {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	.error_detected = e1000_io_error_detected,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	.slot_reset = e1000_io_slot_reset,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.resume = e1000_io_resume,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
static struct pci_driver e1000_driver = {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	.name     = e1000_driver_name,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	.id_table = e1000_pci_tbl,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.probe    = e1000_probe,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.remove   = __devexit_p(e1000_remove),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
#ifdef CONFIG_PM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	/* Power Managment Hooks */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	.suspend  = e1000_suspend,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	.resume   = e1000_resume,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	.shutdown = e1000_shutdown,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	.err_handler = &e1000_err_handler
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
MODULE_LICENSE("GPL");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
MODULE_VERSION(DRV_VERSION);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
module_param(debug, int, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 * e1000_init_module - Driver Registration Routine
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
 * e1000_init_module is the first routine called when the driver is
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
 * loaded. All it does is register with the PCI subsystem.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
static int __init e1000_init_module(void)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	int ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	printk(KERN_INFO "%s - version %s\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	       e1000_driver_string, e1000_driver_version);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	printk(KERN_INFO "%s\n", e1000_copyright);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	ret = pci_register_driver(&e1000_driver);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	if (copybreak != COPYBREAK_DEFAULT) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
		if (copybreak == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
			printk(KERN_INFO "e1000: copybreak disabled\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
			printk(KERN_INFO "e1000: copybreak enabled for "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
			       "packets <= %u bytes\n", copybreak);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	return ret;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
module_init(e1000_init_module);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
 * e1000_exit_module - Driver Exit Cleanup Routine
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
 * e1000_exit_module is called just before the driver is removed
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
 * from memory.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
static void __exit e1000_exit_module(void)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	pci_unregister_driver(&e1000_driver);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
module_exit(e1000_exit_module);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
static int e1000_request_irq(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	irq_handler_t handler = e1000_intr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	int irq_flags = IRQF_SHARED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	int err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
		return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	                  netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		        "Unable to allocate interrupt Error: %d\n", err);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
static void e1000_free_irq(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	free_irq(adapter->pdev->irq, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
 * e1000_irq_disable - Mask off interrupt generation on the NIC
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
static void e1000_irq_disable(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	ew32(IMC, ~0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	synchronize_irq(adapter->pdev->irq);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
 * e1000_irq_enable - Enable default interrupt generation settings
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
static void e1000_irq_enable(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	ew32(IMS, IMS_ENABLE_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	u16 vid = hw->mng_cookie.vlan_id;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	u16 old_vid = adapter->mng_vlan_id;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	if (adapter->vlgrp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
			if (hw->mng_cookie.status &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
				e1000_vlan_rx_add_vid(netdev, vid);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
				adapter->mng_vlan_id = vid;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
			} else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
					(vid != old_vid) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
				e1000_vlan_rx_kill_vid(netdev, old_vid);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		} else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
			adapter->mng_vlan_id = vid;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
static void e1000_init_manageability(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	if (adapter->en_mng_pt) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		u32 manc = er32(MANC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
		/* disable hardware interception of ARP */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
		manc &= ~(E1000_MANC_ARP_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		ew32(MANC, manc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
static void e1000_release_manageability(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	if (adapter->en_mng_pt) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		u32 manc = er32(MANC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		/* re-enable hardware interception of ARP */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		manc |= E1000_MANC_ARP_EN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		ew32(MANC, manc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
 * e1000_configure - configure the hardware for RX and TX
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
 * @adapter = private board structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
static void e1000_configure(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	e1000_set_rx_mode(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	e1000_restore_vlan(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	e1000_init_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	e1000_configure_tx(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	e1000_setup_rctl(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	e1000_configure_rx(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	/* call E1000_DESC_UNUSED which always leaves
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	 * at least 1 descriptor unused to make sure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	 * next_to_use != next_to_clean */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	for (i = 0; i < adapter->num_rx_queues; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
			/* fill rx ring completely! */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
			adapter->alloc_rx_buf(adapter, ring, ring->count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
            /* this one leaves the last ring element unallocated! */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
			adapter->alloc_rx_buf(adapter, ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
					E1000_DESC_UNUSED(ring));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	adapter->tx_queue_len = netdev->tx_queue_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
int e1000_up(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	/* hardware has been reset, we need to reload some things */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	e1000_configure(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	clear_bit(__E1000_DOWN, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		napi_enable(&adapter->napi);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		e1000_irq_enable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
		netif_wake_queue(adapter->netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		/* fire a link change interrupt to start the watchdog */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		ew32(ICS, E1000_ICS_LSC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 * e1000_power_up_phy - restore link in case the phy was powered down
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 * @adapter: address of board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
 * The phy may be powered down to save power and turn off link when the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
 * driver is unloaded and wake on lan is not enabled (among others)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
 * *** this routine MUST be followed by a call to e1000_reset ***
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
void e1000_power_up_phy(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	u16 mii_reg = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	/* Just clear the power down bit to wake the phy back up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	if (hw->media_type == e1000_media_type_copper) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
		/* according to the manual, the phy will retain its
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		 * settings across a power-down/up cycle */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		mii_reg &= ~MII_CR_POWER_DOWN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
static void e1000_power_down_phy(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	/* Power down the PHY so no link is implied when interface is down *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	 * The PHY cannot be powered down if any of the following is true *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	 * (a) WoL is enabled
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	 * (b) AMT is active
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	 * (c) SoL/IDER session is active */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	   hw->media_type == e1000_media_type_copper) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		u16 mii_reg = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		case e1000_82540:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		case e1000_82545:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
				goto out;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
			goto out;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		mii_reg |= MII_CR_POWER_DOWN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		mdelay(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
out:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
void e1000_down(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	u32 rctl, tctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	/* signal that we're down so the interrupt handler does not
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	 * reschedule our watchdog timer */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	set_bit(__E1000_DOWN, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	/* disable receives in the hardware */	
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		/* flush and sleep below */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		netif_tx_disable(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	/* disable transmits in the hardware */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	tctl = er32(TCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	tctl &= ~E1000_TCTL_EN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	ew32(TCTL, tctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	/* flush both disables and wait for them to finish */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	msleep(10);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		napi_disable(&adapter->napi);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		e1000_irq_disable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		del_timer_sync(&adapter->tx_fifo_stall_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		del_timer_sync(&adapter->watchdog_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		del_timer_sync(&adapter->phy_info_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	netdev->tx_queue_len = adapter->tx_queue_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	adapter->link_speed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	adapter->link_duplex = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
		netif_carrier_off(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	e1000_clean_all_tx_rings(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	e1000_clean_all_rx_rings(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
void e1000_reinit_locked(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	WARN_ON(in_interrupt());
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		msleep(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	e1000_down(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	e1000_up(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	clear_bit(__E1000_RESETTING, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
void e1000_reset(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	bool legacy_pba_adjust = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	u16 hwm;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	/* Repartition Pba for greater than 9k mtu
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	 * To take effect CTRL.RST is required.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	case e1000_82540:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
		legacy_pba_adjust = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		pba = E1000_PBA_48K;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	case e1000_82545:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	case e1000_82545_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		pba = E1000_PBA_48K;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		legacy_pba_adjust = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		pba = E1000_PBA_30K;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	case e1000_undefined:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	case e1000_num_macs:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	if (legacy_pba_adjust) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
			pba -= 8; /* allocate more FIFO for Tx */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		if (hw->mac_type == e1000_82547) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
			adapter->tx_fifo_head = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
			adapter->tx_fifo_size =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
			atomic_set(&adapter->tx_fifo_stall, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		/* adjust PBA for jumbo frames */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		ew32(PBA, pba);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		/* To maintain wire speed transmits, the Tx FIFO should be
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		 * large enough to accommodate two full transmit packets,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		 * the Rx FIFO should be large enough to accommodate at least
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		 * one full receive packet and is similarly rounded up and
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		 * expressed in KB. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		pba = er32(PBA);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
		/* upper 16 bits has Tx packet buffer allocation size in KB */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
		tx_space = pba >> 16;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
		/* lower 16 bits has Rx packet buffer allocation size in KB */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		pba &= 0xffff;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
		/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		 * the tx fifo also stores 16 bytes of information about the tx
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		 * but don't include ethernet FCS because hardware appends it
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		min_tx_space = (hw->max_frame_size +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		                sizeof(struct e1000_tx_desc) -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		                ETH_FCS_LEN) * 2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		min_tx_space = ALIGN(min_tx_space, 1024);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		min_tx_space >>= 10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		/* software strips receive CRC, so leave room for it */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		min_rx_space = hw->max_frame_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		min_rx_space = ALIGN(min_rx_space, 1024);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		min_rx_space >>= 10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		/* If current Tx allocation is less than the min Tx FIFO size,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		 * and the min Tx FIFO size is less than the current Rx FIFO
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		 * allocation, take space away from current Rx allocation */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		if (tx_space < min_tx_space &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		    ((min_tx_space - tx_space) < pba)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
			pba = pba - (min_tx_space - tx_space);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
			/* PCI/PCIx hardware has PBA alignment constraints */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
			switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			case e1000_82545 ... e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
				pba &= ~(E1000_PBA_8K - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
			default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
			/* if short on rx space, rx wins and must trump tx
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
			 * adjustment or use Early Receive if available */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
			if (pba < min_rx_space)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
				pba = min_rx_space;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	ew32(PBA, pba);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
	 * flow control settings:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	 * The high water mark must be low enough to fit one full frame
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	 * (or the size used for early receive) above it in the Rx FIFO.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	 * Set it to the lower of:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	 * - 90% of the Rx FIFO size, and
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	 * - the full Rx FIFO size minus the early receive size (for parts
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	 * - the full Rx FIFO size minus one full frame
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	hwm = min(((pba << 10) * 9 / 10),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		  ((pba << 10) - hw->max_frame_size));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	hw->fc_low_water = hw->fc_high_water - 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	hw->fc_send_xon = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	hw->fc = hw->original_fc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	/* Allow time for pending master requests to run */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
	e1000_reset_hw(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if (hw->mac_type >= e1000_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		ew32(WUC, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	if (e1000_init_hw(hw))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		DPRINTK(PROBE, ERR, "Hardware Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	e1000_update_mng_vlan(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	if (hw->mac_type >= e1000_82544 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	    hw->autoneg == 1 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		u32 ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		/* clear phy power management bit if we are in gig only mode,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		 * which if enabled will attempt negotiation to 100Mb, which
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		 * can cause a loss of link at power off or driver unload */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		ctrl &= ~E1000_CTRL_SWDPIN3;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	e1000_reset_adaptive(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	e1000_phy_get_info(hw, &adapter->phy_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	e1000_release_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
 *  Dump the eeprom for users having checksum issues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	struct ethtool_eeprom eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	const struct ethtool_ops *ops = netdev->ethtool_ops;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	u8 *data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	u16 csum_old, csum_new = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	eeprom.len = ops->get_eeprom_len(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	eeprom.offset = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	data = kmalloc(eeprom.len, GFP_KERNEL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	if (!data) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
		       " data\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	ops->get_eeprom(netdev, &eeprom, data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		csum_new += data[i] + (data[i + 1] << 8);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	csum_new = EEPROM_SUM - csum_new;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	printk(KERN_ERR "/*********************/\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	printk(KERN_ERR "Offset    Values\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	printk(KERN_ERR "========  ======\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	printk(KERN_ERR "Include this output when contacting your support "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	       "provider.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	printk(KERN_ERR "This is not a software error! Something bad "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	       "happened to your hardware or\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	printk(KERN_ERR "EEPROM image. Ignoring this "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	       "problem could result in further problems,\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	       "which is invalid\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	printk(KERN_ERR "and requires you to set the proper MAC "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	       "address manually before continuing\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	printk(KERN_ERR "to enable this network device.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	       "to your hardware vendor\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	printk(KERN_ERR "or Intel Customer Support.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	printk(KERN_ERR "/*********************/\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	kfree(data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
 * @pdev: PCI device information struct
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
 * Return true if an adapter needs ioport resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
static int e1000_is_need_ioport(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	switch (pdev->device) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	case E1000_DEV_ID_82540EM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	case E1000_DEV_ID_82540EM_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	case E1000_DEV_ID_82540EP:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	case E1000_DEV_ID_82540EP_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	case E1000_DEV_ID_82540EP_LP:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	case E1000_DEV_ID_82541EI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	case E1000_DEV_ID_82541EI_MOBILE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	case E1000_DEV_ID_82541ER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	case E1000_DEV_ID_82541ER_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	case E1000_DEV_ID_82541GI:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
	case E1000_DEV_ID_82541GI_LF:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	case E1000_DEV_ID_82541GI_MOBILE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	case E1000_DEV_ID_82544EI_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	case E1000_DEV_ID_82544EI_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
	case E1000_DEV_ID_82544GC_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	case E1000_DEV_ID_82544GC_LOM:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	case E1000_DEV_ID_82545EM_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	case E1000_DEV_ID_82545EM_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	case E1000_DEV_ID_82546EB_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	case E1000_DEV_ID_82546EB_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		return true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		return false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
static const struct net_device_ops e1000_netdev_ops = {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	.ndo_open		= e1000_open,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	.ndo_stop		= e1000_close,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	.ndo_start_xmit		= e1000_xmit_frame,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	.ndo_get_stats		= e1000_get_stats,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	.ndo_set_rx_mode	= e1000_set_rx_mode,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	.ndo_set_mac_address	= e1000_set_mac,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	.ndo_tx_timeout 	= e1000_tx_timeout,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	.ndo_change_mtu		= e1000_change_mtu,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	.ndo_do_ioctl		= e1000_ioctl,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	.ndo_validate_addr	= eth_validate_addr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
#ifdef CONFIG_NET_POLL_CONTROLLER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	.ndo_poll_controller	= e1000_netpoll,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
 * e1000_probe - Device Initialization Routine
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
 * @pdev: PCI device information struct
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
 * @ent: entry in e1000_pci_tbl
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
 * Returns 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
 * e1000_probe initializes an adapter identified by a pci_dev structure.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
 * The OS initialization, configuring of the adapter private structure,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
 * and a hardware reset occur.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
static int __devinit e1000_probe(struct pci_dev *pdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
				 const struct pci_device_id *ent)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	struct net_device *netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	struct e1000_adapter *adapter;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	struct e1000_hw *hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	static int cards_found = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	int i, err, pci_using_dac;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	u16 eeprom_data = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	int bars, need_ioport;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	/* do not allocate ioport bars when not needed */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	need_ioport = e1000_is_need_ioport(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	if (need_ioport) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
		err = pci_enable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		err = pci_enable_device_mem(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		pci_using_dac = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
			err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
			if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
				E1000_ERR("No usable DMA configuration, "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
					  "aborting\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
				goto err_dma;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		pci_using_dac = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		goto err_pci_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	pci_set_master(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	err = -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	if (!netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		goto err_alloc_etherdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	SET_NETDEV_DEV(netdev, &pdev->dev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	pci_set_drvdata(pdev, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	adapter->netdev = netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	adapter->pdev = pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	adapter->msg_enable = (1 << debug) - 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	adapter->bars = bars;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	adapter->need_ioport = need_ioport;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	hw->back = adapter;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	err = -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	if (!hw->hw_addr)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		goto err_ioremap;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	if (adapter->need_ioport) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		for (i = BAR_1; i <= BAR_5; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
			if (pci_resource_len(pdev, i) == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
				continue;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
				hw->io_base = pci_resource_start(pdev, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	netdev->netdev_ops = &e1000_netdev_ops;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	e1000_set_ethtool_ops(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	netdev->watchdog_timeo = 5 * HZ;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	adapter->bd_number = cards_found;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	/* setup the private structure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	err = e1000_sw_init(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		goto err_sw_init;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	err = -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	if (hw->mac_type >= e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		netdev->features = NETIF_F_SG |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
				   NETIF_F_HW_CSUM |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
				   NETIF_F_HW_VLAN_TX |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
				   NETIF_F_HW_VLAN_RX |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
				   NETIF_F_HW_VLAN_FILTER;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	if ((hw->mac_type >= e1000_82544) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	   (hw->mac_type != e1000_82547))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		netdev->features |= NETIF_F_TSO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	if (pci_using_dac)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		netdev->features |= NETIF_F_HIGHDMA;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	netdev->vlan_features |= NETIF_F_TSO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	netdev->vlan_features |= NETIF_F_HW_CSUM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	netdev->vlan_features |= NETIF_F_SG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	/* initialize eeprom parameters */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	if (e1000_init_eeprom_params(hw)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
		E1000_ERR("EEPROM initialization failed\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		goto err_eeprom;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	/* before reading the EEPROM, reset the controller to
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	 * put the device in a known good starting state */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	e1000_reset_hw(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	/* make sure the EEPROM is good */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	if (e1000_validate_eeprom_checksum(hw) < 0) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
		e1000_dump_eeprom(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		 * set MAC address to all zeroes to invalidate and temporary
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
		 * disable this device for the user. This blocks regular
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
		 * traffic while still permitting ethtool ioctls from reaching
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		 * the hardware as well as allowing the user to run the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		 * interface after manually setting a hw addr using
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		 * `ip set address`
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		memset(hw->mac_addr, 0, netdev->addr_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		/* copy the MAC address out of the EEPROM */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		if (e1000_read_mac_addr(hw))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	/* don't block initalization here due to bad MAC address */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	if (!is_valid_ether_addr(netdev->perm_addr))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	e1000_get_bus_info(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	init_timer(&adapter->tx_fifo_stall_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	init_timer(&adapter->watchdog_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	adapter->watchdog_timer.function = &e1000_watchdog;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	adapter->watchdog_timer.data = (unsigned long) adapter;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	init_timer(&adapter->phy_info_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	adapter->phy_info_timer.function = &e1000_update_phy_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	adapter->phy_info_timer.data = (unsigned long)adapter;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	e1000_check_options(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	/* Initial Wake on LAN setting
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	 * If APM wake is enabled in the EEPROM,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	 * enable the ACPI Magic Packet filter
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	case e1000_82543:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		e1000_read_eeprom(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	case e1000_82546:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	case e1000_82546_rev_3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
			e1000_read_eeprom(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		/* Fall Through */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		e1000_read_eeprom(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	if (eeprom_data & eeprom_apme_mask)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		adapter->eeprom_wol |= E1000_WUFC_MAG;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	/* now that we have the eeprom settings, apply the special cases
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	 * where the eeprom may be wrong or the board simply won't support
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	 * wake on lan on a particular port */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	switch (pdev->device) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	case E1000_DEV_ID_82546GB_PCIE:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		adapter->eeprom_wol = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	case E1000_DEV_ID_82546EB_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	case E1000_DEV_ID_82546GB_FIBER:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		/* Wake events only supported on port A for dual fiber
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		 * regardless of eeprom setting */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
			adapter->eeprom_wol = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		/* if quad port adapter, disable WoL on all but port A */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		if (global_quad_port_a != 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
			adapter->eeprom_wol = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
			adapter->quad_port_a = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		/* Reset for multiple quad port adapters */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		if (++global_quad_port_a == 4)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
			global_quad_port_a = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	/* initialize the wol settings based on the eeprom settings */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	adapter->wol = adapter->eeprom_wol;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	/* print bus type/speed/width info */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		((hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" : "32-bit"));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	printk("%pM\n", netdev->dev_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	/* reset the hardware with the new settings */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	// offer device to EtherCAT master module
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	if (adapter->ecdev) {
2582
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2471
diff changeset
  1085
		err = ecdev_open(adapter->ecdev);
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2471
diff changeset
  1086
		if (err) {
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
			ecdev_withdraw(adapter->ecdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
			goto err_register;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		strcpy(netdev->name, "eth%d");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		err = register_netdev(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
			goto err_register;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		/* carrier off reporting is important to ethtool even BEFORE open */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		netif_carrier_off(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	cards_found++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
err_register:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
err_eeprom:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	e1000_phy_hw_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	if (hw->flash_address)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		iounmap(hw->flash_address);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	kfree(adapter->tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	kfree(adapter->rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
err_sw_init:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	iounmap(hw->hw_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
err_ioremap:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	free_netdev(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
err_alloc_etherdev:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	pci_release_selected_regions(pdev, bars);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
err_pci_reg:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
err_dma:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	pci_disable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
 * e1000_remove - Device Removal Routine
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
 * @pdev: PCI device information struct
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
 * e1000_remove is called by the PCI subsystem to alert the driver
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
 * that it should release a PCI device.  The could be caused by a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
 * Hot-Plug event, or because the driver is going to be removed from
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
 * memory.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
static void __devexit e1000_remove(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	set_bit(__E1000_DOWN, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		del_timer_sync(&adapter->tx_fifo_stall_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		del_timer_sync(&adapter->watchdog_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		del_timer_sync(&adapter->phy_info_timer);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	cancel_work_sync(&adapter->reset_task);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	e1000_release_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		ecdev_close(adapter->ecdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		ecdev_withdraw(adapter->ecdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		unregister_netdev(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	e1000_phy_hw_reset(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	kfree(adapter->tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	kfree(adapter->rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	iounmap(hw->hw_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	if (hw->flash_address)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		iounmap(hw->flash_address);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	pci_release_selected_regions(pdev, adapter->bars);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	free_netdev(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	pci_disable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
 * @adapter: board private structure to initialize
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
 * e1000_sw_init initializes the Adapter private data structure.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
 * Fields are initialized based on PCI device information and
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
 * OS network device settings (MTU size).
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	/* PCI config space info */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	hw->vendor_id = pdev->vendor;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	hw->device_id = pdev->device;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	hw->subsystem_id = pdev->subsystem_device;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	hw->revision_id = pdev->revision;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	hw->max_frame_size = netdev->mtu +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	/* identify the MAC */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	if (e1000_set_mac_type(hw)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		return -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	case e1000_82541:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	case e1000_82547:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	case e1000_82541_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	case e1000_82547_rev_2:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		hw->phy_init_script = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	e1000_set_media_type(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	hw->wait_autoneg_complete = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	hw->tbi_compatibility_en = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	hw->adaptive_ifs = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	/* Copper options */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	if (hw->media_type == e1000_media_type_copper) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		hw->mdix = AUTO_ALL_MODES;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		hw->disable_polarity_correction = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		hw->master_slave = E1000_MASTER_SLAVE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	adapter->num_tx_queues = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	adapter->num_rx_queues = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	if (e1000_alloc_queues(adapter)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	/* Explicitly disable IRQ since the NIC can be in any state. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	e1000_irq_disable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	spin_lock_init(&adapter->stats_lock);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	set_bit(__E1000_DOWN, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
 * e1000_alloc_queues - Allocate memory for all rings
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
 * @adapter: board private structure to initialize
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
 * We allocate one ring per queue at run-time since we don't know the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
 * number of queues at compile-time.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	if (!adapter->tx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	if (!adapter->rx_ring) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		kfree(adapter->tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
 * e1000_open - Called when a network interface is made active
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
 * Returns 0 on success, negative value on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
 * The open entry point is called when a network interface is made
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
 * active by the system (IFF_UP).  At this point all resources needed
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
 * for transmit and receive operations are allocated, the interrupt
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
 * handler is registered with the OS, the watchdog timer is started,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
 * and the stack is notified that the interface is ready.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
static int e1000_open(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	int err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	/* disallow open during test */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	if (test_bit(__E1000_TESTING, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		return -EBUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	netif_carrier_off(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	/* allocate transmit descriptors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	err = e1000_setup_all_tx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		goto err_setup_tx;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	/* allocate receive descriptors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	err = e1000_setup_all_rx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		goto err_setup_rx;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	e1000_power_up_phy(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	if ((hw->mng_cookie.status &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		e1000_update_mng_vlan(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	/* before we allocate an interrupt, we must be ready to handle it.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	 * as soon as we call pci_request_irq, so we have to setup our
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	 * clean_rx handler before we do so.  */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	e1000_configure(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	err = e1000_request_irq(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		goto err_req_irq;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	/* From here on the code is the same as e1000_up() */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	clear_bit(__E1000_DOWN, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
2469
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1336
	if (!adapter->ecdev) {
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1337
		napi_enable(&adapter->napi);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1338
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1339
		e1000_irq_enable(adapter);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1340
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1341
		netif_start_queue(netdev);
634ba3b1eb95 Fixed possible segfault in e1000_open() function.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  1342
	}
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	/* fire a link status change interrupt to start the watchdog */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	ew32(ICS, E1000_ICS_LSC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
err_req_irq:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	e1000_power_down_phy(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	e1000_free_all_rx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
err_setup_rx:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	e1000_free_all_tx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
err_setup_tx:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 * e1000_close - Disables a network interface
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
 * Returns 0, this is not allowed to fail
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
 * The close entry point is called when an interface is de-activated
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
 * by the OS.  The hardware is still under the drivers control, but
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
 * needs to be disabled.  A global MAC reset is issued to stop the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
 * hardware, and all transmit and receive resources are freed.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
static int e1000_close(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	e1000_down(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	e1000_power_down_phy(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	e1000_free_irq(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	e1000_free_all_tx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	e1000_free_all_rx_resources(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	/* kill manageability vlan ID if supported, but not if a vlan with
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	 * the same ID is registered on the host OS (let 8021q kill it) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	if ((hw->mng_cookie.status &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	     !(adapter->vlgrp &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 * @adapter: address of board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 * @start: address of beginning of memory
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 * @len: length of memory
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
				  unsigned long len)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	unsigned long begin = (unsigned long)start;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	unsigned long end = begin + len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	/* First rev 82545 and 82546 need to not allow any memory
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	 * write location to cross 64k boundary due to errata 23 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	if (hw->mac_type == e1000_82545 ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	    hw->mac_type == e1000_82546) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	return true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
 * @txdr:    tx descriptor ring (for a specific queue) to setup
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
 * Return 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
				    struct e1000_tx_ring *txdr)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	int size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	size = sizeof(struct e1000_buffer) * txdr->count;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	txdr->buffer_info = vmalloc(size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	if (!txdr->buffer_info) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		"Unable to allocate memory for the transmit descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	memset(txdr->buffer_info, 0, size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	/* round up to nearest 4K */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	txdr->size = ALIGN(txdr->size, 4096);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	if (!txdr->desc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
setup_tx_desc_die:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		vfree(txdr->buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		"Unable to allocate memory for the transmit descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	/* Fix for errata 23, can't cross 64kB boundary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		void *olddesc = txdr->desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		dma_addr_t olddma = txdr->dma;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
				     "at %p\n", txdr->size, txdr->desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		/* Try again, without freeing the previous */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		/* Failed allocation, critical failure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		if (!txdr->desc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
			goto setup_tx_desc_die;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
			/* give up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
			pci_free_consistent(pdev, txdr->size, txdr->desc,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
					    txdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
			DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
				"Unable to allocate aligned memory "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
				"for the transmit descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			vfree(txdr->buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
			return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
			/* Free old allocation, new allocation was successful */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	memset(txdr->desc, 0, txdr->size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	txdr->next_to_use = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	txdr->next_to_clean = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
 * 				  (Descriptors) for all queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
 * Return 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	int i, err = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	for (i = 0; i < adapter->num_tx_queues; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
			DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
				"Allocation for Tx Queue %u failed\n", i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
			for (i-- ; i >= 0; i--)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
				e1000_free_tx_resources(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
							&adapter->tx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
 * Configure the Tx unit of the MAC after a reset.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
static void e1000_configure_tx(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	u64 tdba;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	u32 tdlen, tctl, tipg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	u32 ipgr1, ipgr2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	/* Setup the HW Tx Head and Tail descriptor pointers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	switch (adapter->num_tx_queues) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	case 1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		tdba = adapter->tx_ring[0].dma;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		tdlen = adapter->tx_ring[0].count *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
			sizeof(struct e1000_tx_desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		ew32(TDLEN, tdlen);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		ew32(TDBAH, (tdba >> 32));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		ew32(TDT, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		ew32(TDH, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	/* Set the default values for the Tx Inter Packet Gap timer */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	if ((hw->media_type == e1000_media_type_fiber ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	     hw->media_type == e1000_media_type_internal_serdes))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	case e1000_82542_rev2_0:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	case e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		tipg = DEFAULT_82542_TIPG_IPGT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	ew32(TIPG, tipg);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	/* Set the Tx Interrupt Delay register */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	ew32(TIDV, adapter->tx_int_delay);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
	if (hw->mac_type >= e1000_82540)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		ew32(TADV, adapter->tx_abs_int_delay);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	/* Program the Transmit Control Register */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	tctl = er32(TCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	tctl &= ~E1000_TCTL_CT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	e1000_config_collision_dist(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	/* Setup Transmit Descriptor Settings for eop descriptor */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	/* only set IDE if we are delaying interrupts using the timers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	if (adapter->tx_int_delay)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (hw->mac_type < e1000_82543)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	/* Cache if we're 82544 running in PCI-X because we'll
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	 * need this to apply a workaround later in the send path. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	if (hw->mac_type == e1000_82544 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	    hw->bus_type == e1000_bus_type_pcix)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		adapter->pcix_82544 = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	ew32(TCTL, tctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
 * Returns 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
				    struct e1000_rx_ring *rxdr)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	int size, desc_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	size = sizeof(struct e1000_buffer) * rxdr->count;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	rxdr->buffer_info = vmalloc(size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	if (!rxdr->buffer_info) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		"Unable to allocate memory for the receive descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	memset(rxdr->buffer_info, 0, size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	desc_len = sizeof(struct e1000_rx_desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	/* Round up to nearest 4K */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	rxdr->size = rxdr->count * desc_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	rxdr->size = ALIGN(rxdr->size, 4096);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	if (!rxdr->desc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		"Unable to allocate memory for the receive descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
setup_rx_desc_die:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		vfree(rxdr->buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		return -ENOMEM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	/* Fix for errata 23, can't cross 64kB boundary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		void *olddesc = rxdr->desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		dma_addr_t olddma = rxdr->dma;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
				     "at %p\n", rxdr->size, rxdr->desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		/* Try again, without freeing the previous */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		/* Failed allocation, critical failure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		if (!rxdr->desc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
			DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
				"Unable to allocate memory "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
				"for the receive descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			goto setup_rx_desc_die;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			/* give up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
					    rxdr->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
				"Unable to allocate aligned memory "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
				"for the receive descriptor ring\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
			goto setup_rx_desc_die;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
			/* Free old allocation, new allocation was successful */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	memset(rxdr->desc, 0, rxdr->size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	rxdr->next_to_clean = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	rxdr->next_to_use = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	rxdr->rx_skb_top = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
 * 				  (Descriptors) for all queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
 * Return 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	int i, err = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	for (i = 0; i < adapter->num_rx_queues; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
			DPRINTK(PROBE, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
				"Allocation for Rx Queue %u failed\n", i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
			for (i-- ; i >= 0; i--)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
				e1000_free_rx_resources(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
							&adapter->rx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
 * e1000_setup_rctl - configure the receive control registers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
 * @adapter: Board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
static void e1000_setup_rctl(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	u32 rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	if (hw->tbi_compatibility_on == 1)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		rctl |= E1000_RCTL_SBP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		rctl &= ~E1000_RCTL_SBP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		rctl &= ~E1000_RCTL_LPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		rctl |= E1000_RCTL_LPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	/* Setup buffer sizes */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	rctl &= ~E1000_RCTL_SZ_4096;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	rctl |= E1000_RCTL_BSEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	switch (adapter->rx_buffer_len) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		case E1000_RXBUFFER_2048:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
			rctl |= E1000_RCTL_SZ_2048;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
			rctl &= ~E1000_RCTL_BSEX;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		case E1000_RXBUFFER_4096:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			rctl |= E1000_RCTL_SZ_4096;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		case E1000_RXBUFFER_8192:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
			rctl |= E1000_RCTL_SZ_8192;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		case E1000_RXBUFFER_16384:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
			rctl |= E1000_RCTL_SZ_16384;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
 * Configure the Rx unit of the MAC after a reset.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
static void e1000_configure_rx(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	u64 rdba;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	u32 rdlen, rctl, rxcsum;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		rdlen = adapter->rx_ring[0].count *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		        sizeof(struct e1000_rx_desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		rdlen = adapter->rx_ring[0].count *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		        sizeof(struct e1000_rx_desc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		adapter->clean_rx = e1000_clean_rx_irq;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	/* disable receives while setting up the descriptors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	/* set the Receive Delay Timer Register */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	ew32(RDTR, adapter->rx_int_delay);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	if (hw->mac_type >= e1000_82540) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		ew32(RADV, adapter->rx_abs_int_delay);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		if (adapter->itr_setting != 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
			ew32(ITR, 1000000000 / (adapter->itr * 256));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	 * the Base and Length of the Rx Descriptor Ring */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	switch (adapter->num_rx_queues) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	case 1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		rdba = adapter->rx_ring[0].dma;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		ew32(RDLEN, rdlen);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		ew32(RDBAH, (rdba >> 32));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		ew32(RDT, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		ew32(RDH, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	if (hw->mac_type >= e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		rxcsum = er32(RXCSUM);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		if (adapter->rx_csum)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
			rxcsum |= E1000_RXCSUM_TUOFL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
			/* don't need to clear IPPCSE as it defaults to 0 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
			rxcsum &= ~E1000_RXCSUM_TUOFL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		ew32(RXCSUM, rxcsum);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	/* Enable Receives */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
 * e1000_free_tx_resources - Free Tx Resources per Queue
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
 * @tx_ring: Tx descriptor ring for a specific queue
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
 * Free all transmit software resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
				    struct e1000_tx_ring *tx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	e1000_clean_tx_ring(adapter, tx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	vfree(tx_ring->buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	tx_ring->buffer_info = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	tx_ring->desc = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
 * Free all transmit software resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	for (i = 0; i < adapter->num_tx_queues; i++)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
					     struct e1000_buffer *buffer_info)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	buffer_info->dma = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	if (buffer_info->skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		              DMA_TO_DEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		dev_kfree_skb_any(buffer_info->skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		buffer_info->skb = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	buffer_info->time_stamp = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	/* buffer_info must be completely set up in the transmit path */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
 * e1000_clean_tx_ring - Free Tx Buffers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
 * @tx_ring: ring to be cleaned
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
				struct e1000_tx_ring *tx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	unsigned long size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	/* Free all the Tx ring sk_buffs */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	for (i = 0; i < tx_ring->count; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	size = sizeof(struct e1000_buffer) * tx_ring->count;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	memset(tx_ring->buffer_info, 0, size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	/* Zero out the descriptor ring */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	memset(tx_ring->desc, 0, tx_ring->size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	tx_ring->next_to_use = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	tx_ring->next_to_clean = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	tx_ring->last_tx_tso = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	writel(0, hw->hw_addr + tx_ring->tdh);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	writel(0, hw->hw_addr + tx_ring->tdt);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	for (i = 0; i < adapter->num_tx_queues; i++)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
 * e1000_free_rx_resources - Free Rx Resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
 * @rx_ring: ring to clean the resources from
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
 * Free all receive software resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
				    struct e1000_rx_ring *rx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	e1000_clean_rx_ring(adapter, rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	vfree(rx_ring->buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	rx_ring->buffer_info = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	rx_ring->desc = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 * Free all receive software resources
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	for (i = 0; i < adapter->num_rx_queues; i++)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
 * @rx_ring: ring to free buffers from
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
				struct e1000_rx_ring *rx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	unsigned long size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	/* Free all the Rx ring sk_buffs */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	for (i = 0; i < rx_ring->count; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		if (buffer_info->dma &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		    adapter->clean_rx == e1000_clean_rx_irq) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
			pci_unmap_single(pdev, buffer_info->dma,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
			                 buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
			                 PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		} else if (buffer_info->dma &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
			pci_unmap_page(pdev, buffer_info->dma,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
			               buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
			               PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
		buffer_info->dma = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		if (buffer_info->page) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
			put_page(buffer_info->page);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
			buffer_info->page = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		if (buffer_info->skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
			dev_kfree_skb(buffer_info->skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
			buffer_info->skb = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	/* there also may be some cached data from a chained receive */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	if (rx_ring->rx_skb_top) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
		dev_kfree_skb(rx_ring->rx_skb_top);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
		rx_ring->rx_skb_top = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	size = sizeof(struct e1000_buffer) * rx_ring->count;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	memset(rx_ring->buffer_info, 0, size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	/* Zero out the descriptor ring */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	memset(rx_ring->desc, 0, rx_ring->size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	rx_ring->next_to_clean = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	rx_ring->next_to_use = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	writel(0, hw->hw_addr + rx_ring->rdh);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	writel(0, hw->hw_addr + rx_ring->rdt);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	for (i = 0; i < adapter->num_rx_queues; i++)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
 * and memory write and invalidate disabled for certain operations
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	u32 rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	e1000_pci_clear_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	rctl |= E1000_RCTL_RST;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	mdelay(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	if (!adapter->ecdev && netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		e1000_clean_all_rx_rings(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	u32 rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	rctl &= ~E1000_RCTL_RST;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	mdelay(5);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
		e1000_pci_set_mwi(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	if (!adapter->netdev && netif_running(netdev)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
		/* No need to loop, because 82542 supports only 1 queue */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
		e1000_configure_rx(adapter);
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2214
diff changeset
  2094
		if (adapter->ecdev) {
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			/* fill rx ring completely! */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			adapter->alloc_rx_buf(adapter, ring, ring->count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
            /* this one leaves the last ring element unallocated! */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
 * e1000_set_mac - Change the Ethernet Address of the NIC
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
 * @p: pointer to an address structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
 * Returns 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
static int e1000_set_mac(struct net_device *netdev, void *p)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	struct sockaddr *addr = p;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	if (!is_valid_ether_addr(addr->sa_data))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
		return -EADDRNOTAVAIL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	/* 82542 2.0 needs to be in reset to write receive address registers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	if (hw->mac_type == e1000_82542_rev2_0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		e1000_enter_82542_rst(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	e1000_rar_set(hw, hw->mac_addr, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	if (hw->mac_type == e1000_82542_rev2_0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
		e1000_leave_82542_rst(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 * The set_rx_mode entry point is called whenever the unicast or multicast
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 * address lists or the network interface flags are updated. This routine is
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
 * responsible for configuring the hardware for proper unicast, multicast,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * promiscuous mode, and all-multi behavior.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
static void e1000_set_rx_mode(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	struct netdev_hw_addr *ha;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	bool use_uc = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	struct dev_addr_list *mc_ptr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	u32 rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	u32 hash_value;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	int i, rar_entries = E1000_RAR_ENTRIES;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	if (!mcarray) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		DPRINTK(PROBE, ERR, "memory allocation failed\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	/* Check for Promiscuous and All Multicast modes */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	if (netdev->flags & IFF_PROMISC) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		rctl &= ~E1000_RCTL_VFE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		if (netdev->flags & IFF_ALLMULTI)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
			rctl |= E1000_RCTL_MPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			rctl &= ~E1000_RCTL_MPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		/* Enable VLAN filter if there is a VLAN */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		if (adapter->vlgrp)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			rctl |= E1000_RCTL_VFE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	if (netdev->uc.count > rar_entries - 1) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		rctl |= E1000_RCTL_UPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	} else if (!(netdev->flags & IFF_PROMISC)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
		rctl &= ~E1000_RCTL_UPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		use_uc = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	/* 82542 2.0 needs to be in reset to write receive address registers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	if (hw->mac_type == e1000_82542_rev2_0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		e1000_enter_82542_rst(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	/* load the first 14 addresses into the exact filters 1-14. Unicast
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	 * addresses take precedence to avoid disabling unicast filtering
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	 * when possible.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	 * RAR 0 is used for the station MAC adddress
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	 * if there are not 14 addresses, go ahead and clear the filters
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	i = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	if (use_uc)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
		list_for_each_entry(ha, &netdev->uc.list, list) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			if (i == rar_entries)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
			e1000_rar_set(hw, ha->addr, i++);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	WARN_ON(i == rar_entries);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	mc_ptr = netdev->mc_list;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	for (; i < rar_entries; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
		if (mc_ptr) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
			e1000_rar_set(hw, mc_ptr->da_addr, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
			mc_ptr = mc_ptr->next;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
			E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	/* load any remaining addresses into the hash table */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
		u32 hash_reg, hash_bit, mta;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
		hash_reg = (hash_value >> 5) & 0x7F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
		hash_bit = hash_value & 0x1F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		mta = (1 << hash_bit);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
		mcarray[hash_reg] |= mta;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	/* write the hash table completely, write from bottom to avoid
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	 * both stupid write combining chipsets, and flushing each write */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		 * If we are on an 82544 has an errata where writing odd
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		 * offsets overwrites the previous even offset, but writing
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		 * backwards over the range solves the issue by always
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		 * writing the odd offset first
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	if (hw->mac_type == e1000_82542_rev2_0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
		e1000_leave_82542_rst(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	kfree(mcarray);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
/* Need to wait a few seconds after link up to get diagnostic information from
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
 * the phy */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
static void e1000_update_phy_info(unsigned long data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	e1000_phy_get_info(hw, &adapter->phy_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
 * e1000_82547_tx_fifo_stall - Timer Call-back
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
 * @data: pointer to adapter cast into an unsigned long
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
static void e1000_82547_tx_fifo_stall(unsigned long data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	u32 tctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	if (atomic_read(&adapter->tx_fifo_stall)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
		if ((er32(TDT) == er32(TDH)) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
		   (er32(TDFT) == er32(TDFH)) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
		   (er32(TDFTS) == er32(TDFHS))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
			tctl = er32(TCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
			ew32(TDFT, adapter->tx_head_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
			ew32(TDFH, adapter->tx_head_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
			ew32(TDFTS, adapter->tx_head_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
			ew32(TDFHS, adapter->tx_head_addr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
			ew32(TCTL, tctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
			E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
			adapter->tx_fifo_head = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
			atomic_set(&adapter->tx_fifo_stall, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
			if (!adapter->ecdev) netif_wake_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2214
diff changeset
  2297
			if (!adapter->ecdev)
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
static bool e1000_has_link(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	bool link_active = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	/* get_link_status is set on LSC (link status) interrupt or
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	 * rx sequence error interrupt.  get_link_status will stay
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	 * false until the e1000_check_for_link establishes link
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	 * for copper adapters ONLY
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	switch (hw->media_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	case e1000_media_type_copper:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		if (hw->get_link_status) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
			e1000_check_for_link(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
			link_active = !hw->get_link_status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			link_active = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	case e1000_media_type_fiber:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		e1000_check_for_link(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	case e1000_media_type_internal_serdes:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		e1000_check_for_link(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		link_active = hw->serdes_has_link;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	return link_active;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
 * e1000_watchdog - Timer Call-back
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
 * @data: pointer to adapter cast into an unsigned long
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
static void e1000_watchdog(unsigned long data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	struct e1000_tx_ring *txdr = adapter->tx_ring;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	u32 link, tctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	link = e1000_has_link(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
		goto link_up;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	if (link) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
			u32 ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
			bool txb2b = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
			/* update snapshot of PHY registers on LSC */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
			e1000_get_speed_and_duplex(hw,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
			                           &adapter->link_speed,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
			                           &adapter->link_duplex);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
			ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
			printk(KERN_INFO "e1000: %s NIC Link is Up %d Mbps %s, "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
			       "Flow Control: %s\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
			       netdev->name,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
			       adapter->link_speed,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
			       adapter->link_duplex == FULL_DUPLEX ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
			        "Full Duplex" : "Half Duplex",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			/* tweak tx_queue_len according to speed/duplex
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			 * and adjust the timeout factor */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			netdev->tx_queue_len = adapter->tx_queue_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			adapter->tx_timeout_factor = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			switch (adapter->link_speed) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			case SPEED_10:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
				txb2b = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
				netdev->tx_queue_len = 10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
				adapter->tx_timeout_factor = 16;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
			case SPEED_100:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
				txb2b = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
				netdev->tx_queue_len = 100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
				/* maybe add some timeout factor ? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			/* enable transmits in the hardware */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			tctl = er32(TCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
			tctl |= E1000_TCTL_EN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			ew32(TCTL, tctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
			if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
				ecdev_set_link(adapter->ecdev, 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
				netif_carrier_on(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
				if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
					mod_timer(&adapter->phy_info_timer,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
					          round_jiffies(jiffies + 2 * HZ));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			adapter->smartspeed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
			adapter->link_speed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
			adapter->link_duplex = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			printk(KERN_INFO "e1000: %s NIC Link is Down\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
			       netdev->name);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
			if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
				ecdev_set_link(adapter->ecdev, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
				netif_carrier_off(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
				if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
					mod_timer(&adapter->phy_info_timer,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
					          round_jiffies(jiffies + 2 * HZ));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		e1000_smartspeed(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
link_up:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	e1000_update_stats(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	adapter->tpt_old = adapter->stats.tpt;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	adapter->colc_old = adapter->stats.colc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	adapter->gorcl_old = adapter->stats.gorcl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	adapter->gotcl_old = adapter->stats.gotcl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	e1000_update_adaptive(hw);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
			/* We've lost link, so the controller stops DMA,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
			 * but we've got queued Tx work that's never going
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
			 * to get done, so reset controller to flush Tx.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
			 * (Do the reset outside of interrupt context). */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
			adapter->tx_timeout_count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
			schedule_work(&adapter->reset_task);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
			/* return immediately since reset is imminent */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
			return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	/* Cause software interrupt to ensure rx ring is cleaned */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	ew32(ICS, E1000_ICS_RXDMT0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	/* Force detection of hung controller every watchdog period */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	if (!adapter->ecdev) adapter->detect_tx_hung = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	/* Reset the timer */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			mod_timer(&adapter->watchdog_timer,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			          round_jiffies(jiffies + 2 * HZ));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
enum latency_range {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
	lowest_latency = 0,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	low_latency = 1,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	bulk_latency = 2,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	latency_invalid = 255
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
};
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
 * e1000_update_itr - update the dynamic ITR value based on statistics
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
 * @adapter: pointer to adapter
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
 * @itr_setting: current adapter->itr
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
 * @packets: the number of packets during this measurement interval
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
 * @bytes: the number of bytes during this measurement interval
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
 *      Stores a new ITR value based on packets and byte
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
 *      counts during the last interrupt.  The advantage of per interrupt
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
 *      computation is faster updates and more accurate ITR for the current
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
 *      traffic pattern.  Constants in this function were computed
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
 *      based on theoretical maximum wire speed and thresholds were set based
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
 *      on testing data as well as attempting to minimize response time
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
 *      while increasing bulk throughput.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
 *      this functionality is controlled by the InterruptThrottleRate module
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
 *      parameter (see e1000_param.c)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
				     u16 itr_setting, int packets, int bytes)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	unsigned int retval = itr_setting;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	if (unlikely(hw->mac_type < e1000_82540))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		goto update_itr_done;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	if (packets == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		goto update_itr_done;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	switch (itr_setting) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	case lowest_latency:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		/* jumbo frames get bulk treatment*/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		if (bytes/packets > 8000)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			retval = bulk_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		else if ((packets < 5) && (bytes > 512))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
			retval = low_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	case low_latency:  /* 50 usec aka 20000 ints/s */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		if (bytes > 10000) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
			/* jumbo frames need bulk latency setting */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
			if (bytes/packets > 8000)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
				retval = bulk_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
			else if ((packets < 10) || ((bytes/packets) > 1200))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
				retval = bulk_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			else if ((packets > 35))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
				retval = lowest_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		} else if (bytes/packets > 2000)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
			retval = bulk_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		else if (packets <= 2 && bytes < 512)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			retval = lowest_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	case bulk_latency: /* 250 usec aka 4000 ints/s */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		if (bytes > 25000) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			if (packets > 35)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
				retval = low_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		} else if (bytes < 6000) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			retval = low_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
update_itr_done:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	return retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
static void e1000_set_itr(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	u16 current_itr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	u32 new_itr = adapter->itr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	if (unlikely(hw->mac_type < e1000_82540))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	if (unlikely(adapter->link_speed != SPEED_1000)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		current_itr = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		new_itr = 4000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		goto set_itr_now;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	adapter->tx_itr = e1000_update_itr(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	                            adapter->tx_itr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	                            adapter->total_tx_packets,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	                            adapter->total_tx_bytes);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		adapter->tx_itr = low_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	adapter->rx_itr = e1000_update_itr(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	                            adapter->rx_itr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
	                            adapter->total_rx_packets,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	                            adapter->total_rx_bytes);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		adapter->rx_itr = low_latency;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	switch (current_itr) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	/* counts and packets in update_itr are dependent on these numbers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	case lowest_latency:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		new_itr = 70000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	case low_latency:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		new_itr = 20000; /* aka hwitr = ~200 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
	case bulk_latency:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
		new_itr = 4000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
set_itr_now:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	if (new_itr != adapter->itr) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		/* this attempts to bias the interrupt rate towards Bulk
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		 * by adding intermediate steps when interrupt rate is
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		 * increasing */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		new_itr = new_itr > adapter->itr ?
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		             min(adapter->itr + (new_itr >> 2), new_itr) :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		             new_itr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		adapter->itr = new_itr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
		ew32(ITR, 1000000000 / (new_itr * 256));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
#define E1000_TX_FLAGS_CSUM		0x00000001
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
#define E1000_TX_FLAGS_VLAN		0x00000002
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
#define E1000_TX_FLAGS_TSO		0x00000004
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
#define E1000_TX_FLAGS_IPV4		0x00000008
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
#define E1000_TX_FLAGS_VLAN_SHIFT	16
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
static int e1000_tso(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	struct e1000_context_desc *context_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 cmd_length = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	u16 ipcse = 0, tucse, mss;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	int err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	if (skb_is_gso(skb)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		if (skb_header_cloned(skb)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
			if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
				return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
		mss = skb_shinfo(skb)->gso_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
		if (skb->protocol == htons(ETH_P_IP)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
			struct iphdr *iph = ip_hdr(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
			iph->tot_len = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
			iph->check = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
								 iph->daddr, 0,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
								 IPPROTO_TCP,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
								 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			cmd_length = E1000_TXD_CMD_IP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			ipcse = skb_transport_offset(skb) - 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			ipv6_hdr(skb)->payload_len = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
			tcp_hdr(skb)->check =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
						 &ipv6_hdr(skb)->daddr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
						 0, IPPROTO_TCP, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
			ipcse = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		ipcss = skb_network_offset(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
		tucss = skb_transport_offset(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		tucse = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
		i = tx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		context_desc->upper_setup.tcp_fields.tucss = tucss;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		context_desc->upper_setup.tcp_fields.tucso = tucso;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		buffer_info->time_stamp = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		buffer_info->next_to_watch = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		if (++i == tx_ring->count) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		tx_ring->next_to_use = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		return true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	return false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
static bool e1000_tx_csum(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	struct e1000_context_desc *context_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	u8 css;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	u32 cmd_len = E1000_TXD_CMD_DEXT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	if (skb->ip_summed != CHECKSUM_PARTIAL)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		return false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	switch (skb->protocol) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	case cpu_to_be16(ETH_P_IP):
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
			cmd_len |= E1000_TXD_CMD_TCP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	case cpu_to_be16(ETH_P_IPV6):
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		/* XXX not handling all IPV6 headers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
			cmd_len |= E1000_TXD_CMD_TCP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		if (unlikely(net_ratelimit()))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			DPRINTK(DRV, WARNING,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
			        "checksum_partial proto=%x!\n", skb->protocol);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	css = skb_transport_offset(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	i = tx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	context_desc->lower_setup.ip_config = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	context_desc->upper_setup.tcp_fields.tucss = css;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	context_desc->upper_setup.tcp_fields.tucso =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		css + skb->csum_offset;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	context_desc->upper_setup.tcp_fields.tucse = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
	context_desc->tcp_seg_setup.data = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	buffer_info->time_stamp = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	buffer_info->next_to_watch = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	if (unlikely(++i == tx_ring->count)) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
	tx_ring->next_to_use = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	return true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
#define E1000_MAX_TXD_PWR	12
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
static int e1000_tx_map(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
			struct e1000_tx_ring *tx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
			struct sk_buff *skb, unsigned int first,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
			unsigned int max_per_txd, unsigned int nr_frags,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			unsigned int mss)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	unsigned int len = skb_headlen(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	unsigned int offset, size, count = 0, i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	unsigned int f;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	dma_addr_t *map;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	i = tx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
		return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	map = skb_shinfo(skb)->dma_maps;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	offset = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	while (len) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		size = min(len, max_per_txd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		/* Workaround for Controller erratum --
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		 * descriptor for non-tso packet in a linear SKB that follows a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		 * tso gets written back prematurely before the data is fully
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		 * DMA'd to the controller */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		if (!skb->data_len && tx_ring->last_tx_tso &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		    !skb_is_gso(skb)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			tx_ring->last_tx_tso = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			size -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		/* Workaround for premature desc write-backs
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		 * in TSO mode.  Append 4-byte sentinel desc */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		if (unlikely(mss && !nr_frags && size == len && size > 8))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
			size -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		/* work-around for errata 10 and it applies
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		 * to all controllers in PCI-X mode
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		 * The fix is to make sure that the first descriptor of a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		                (size > 2015) && count == 0))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		        size = 2015;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		 * terminating buffers within evenly-aligned dwords. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		if (unlikely(adapter->pcix_82544 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		   size > 4))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
			size -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		buffer_info->length = size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		/* set time_stamp *before* dma to help avoid a possible race */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		buffer_info->time_stamp = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
		buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
		buffer_info->next_to_watch = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		len -= size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		offset += size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		if (len) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			i++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
			if (unlikely(i == tx_ring->count))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
				i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	for (f = 0; f < nr_frags; f++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		struct skb_frag_struct *frag;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		frag = &skb_shinfo(skb)->frags[f];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		len = frag->size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
		offset = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		while (len) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
			i++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
			if (unlikely(i == tx_ring->count))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
				i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
			buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
			size = min(len, max_per_txd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
			/* Workaround for premature desc write-backs
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
			 * in TSO mode.  Append 4-byte sentinel desc */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
				size -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
			/* Workaround for potential 82544 hang in PCI-X.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			 * Avoid terminating buffers within evenly-aligned
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
			 * dwords. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
			if (unlikely(adapter->pcix_82544 &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
			    !((unsigned long)(page_to_phys(frag->page) + offset
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			                      + size - 1) & 4) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
			    size > 4))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
				size -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
			buffer_info->length = size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			buffer_info->time_stamp = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			buffer_info->dma = map[f] + offset;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
			buffer_info->next_to_watch = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
			len -= size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
			offset += size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
			count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	tx_ring->buffer_info[i].skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	tx_ring->buffer_info[first].next_to_watch = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	return count;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
static void e1000_tx_queue(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
			   struct e1000_tx_ring *tx_ring, int tx_flags,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			   int count)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	struct e1000_tx_desc *tx_desc = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		             E1000_TXD_CMD_TSE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		txd_lower |= E1000_TXD_CMD_VLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	i = tx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	while (count--) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		tx_desc = E1000_TX_DESC(*tx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		tx_desc->lower.data =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
			cpu_to_le32(txd_lower | buffer_info->length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		tx_desc->upper.data = cpu_to_le32(txd_upper);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		if (unlikely(++i == tx_ring->count)) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	/* Force memory writes to complete before letting h/w
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	 * know there are new descriptors to fetch.  (Only
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	 * applicable for weak-ordered memory model archs,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	 * such as IA-64). */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	wmb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	tx_ring->next_to_use = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	writel(i, hw->hw_addr + tx_ring->tdt);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	/* we need this if more than one processor can write to our tail
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	 * at a time, it syncronizes IO on IA64/Altix systems */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	mmiowb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
 * 82547 workaround to avoid controller hang in half-duplex environment.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
 * The workaround is to avoid queuing a large packet that would span
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
 * the internal Tx FIFO ring boundary by notifying the stack to resend
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
 * to the beginning of the Tx FIFO.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
#define E1000_FIFO_HDR			0x10
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
#define E1000_82547_PAD_LEN		0x3E0
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
				       struct sk_buff *skb)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	if (adapter->link_duplex != HALF_DUPLEX)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		goto no_fifo_stall_required;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	if (atomic_read(&adapter->tx_fifo_stall))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		return 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		atomic_set(&adapter->tx_fifo_stall, 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		return 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
no_fifo_stall_required:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	adapter->tx_fifo_head += skb_fifo_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
2471
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  2955
	if (adapter->ecdev) {
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  2956
		return -EBUSY;
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  2957
	}
fc64a4b1ec1a Fixed __e1000_maybe_stop_tx().
Florian Pose <fp@igh-essen.com>
parents: 2469
diff changeset
  2958
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	netif_stop_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	/* Herbert's original patch had:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	 *  smp_mb__after_netif_stop_queue();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	 * but since that doesn't exist yet, just open code it. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	smp_mb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	/* We need to check again in a case another CPU has just
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	 * made room available. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		return -EBUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	/* A reprieve! */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
	netif_start_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	++adapter->restart_queue;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
static int e1000_maybe_stop_tx(struct net_device *netdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
                               struct e1000_tx_ring *tx_ring, int size)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	return __e1000_maybe_stop_tx(netdev, size);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
				    struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
	struct e1000_tx_ring *tx_ring;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	unsigned int tx_flags = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	unsigned int len = skb->len - skb->data_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	unsigned int nr_frags = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	unsigned int mss = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	int count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	int tso;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	unsigned int f;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	/* This goes back to the question of how to logically map a tx queue
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	 * to a flow.  Right now, performance is impacted slightly negatively
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	 * if using multiple tx queues.  If the stack breaks away from a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	 * single qdisc implementation, we can look at this again. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	tx_ring = adapter->tx_ring;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	if (unlikely(skb->len <= 0)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		if (!adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
			dev_kfree_skb_any(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		return NETDEV_TX_OK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	mss = skb_shinfo(skb)->gso_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	/* The controller does a simple calculation to
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	 * make sure there is enough room in the FIFO before
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	 * initiating the DMA for each buffer.  The calc is:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	 * 4 = ceil(buffer len/mss).  To make sure we don't
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	 * overrun the FIFO, adjust the max buffer len if mss
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	 * drops. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
	if (mss) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		u8 hdr_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		max_per_txd = min(mss << 2, max_per_txd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		max_txd_pwr = fls(max_per_txd) - 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
		if (skb->data_len && hdr_len == len) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
			switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
				unsigned int pull_size;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
			case e1000_82544:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
				/* Make sure we have room to chop off 4 bytes,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
				 * and that the end alignment will work out to
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
				 * this hardware's requirements
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
				 * NOTE: this is a TSO only workaround
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
				 * if end byte alignment not correct move us
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
				 * into the next dword */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
					break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
				/* fall through */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
				pull_size = min((unsigned int)4, skb->data_len);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
				if (!__pskb_pull_tail(skb, pull_size)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
					DPRINTK(DRV, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
						"__pskb_pull_tail failed.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
					dev_kfree_skb_any(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
					return NETDEV_TX_OK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
				len = skb->len - skb->data_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
			default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
				/* do nothing */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	/* reserve a descriptor for the offload context */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	/* Controller Erratum workaround */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	count += TXD_USE_COUNT(len, max_txd_pwr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	if (adapter->pcix_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	/* work-around for errata 10 and it applies to all controllers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	 * in PCI-X mode, so add one more descriptor to the count
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
			(len > 2015)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	nr_frags = skb_shinfo(skb)->nr_frags;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	for (f = 0; f < nr_frags; f++)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
				       max_txd_pwr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	if (adapter->pcix_82544)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		count += nr_frags;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	/* need: count + 2 desc gap to keep tail from touching
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	 * head, otherwise try next time */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		return NETDEV_TX_BUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	if (unlikely(hw->mac_type == e1000_82547)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
			if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
				netif_stop_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
				if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
					mod_timer(&adapter->tx_fifo_stall_timer,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
					          jiffies + 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
			return NETDEV_TX_BUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		tx_flags |= E1000_TX_FLAGS_VLAN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	first = tx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	tso = e1000_tso(adapter, tx_ring, skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	if (tso < 0) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
			dev_kfree_skb_any(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
		return NETDEV_TX_OK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	if (likely(tso)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		if (likely(hw->mac_type != e1000_82544))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
			tx_ring->last_tx_tso = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
		tx_flags |= E1000_TX_FLAGS_TSO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
		tx_flags |= E1000_TX_FLAGS_CSUM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	if (likely(skb->protocol == htons(ETH_P_IP)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		tx_flags |= E1000_TX_FLAGS_IPV4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	                     nr_frags, mss);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	if (count) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
			/* Make sure there is space in the ring for the next send. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
			e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		if (!adapter->ecdev) dev_kfree_skb_any(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
		tx_ring->buffer_info[first].time_stamp = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
		tx_ring->next_to_use = first;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	return NETDEV_TX_OK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
 * e1000_tx_timeout - Respond to a Tx Hang
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
static void e1000_tx_timeout(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	/* Do the reset outside of interrupt context */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	adapter->tx_timeout_count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	schedule_work(&adapter->reset_task);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
static void e1000_reset_task(struct work_struct *work)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	struct e1000_adapter *adapter =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		container_of(work, struct e1000_adapter, reset_task);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	e1000_reinit_locked(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
 * e1000_get_stats - Get System Network Statistics
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
 * Returns the address of the device statistics structure.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
 * The statistics are actually updated from the timer callback.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	/* only return the current stats */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	return &adapter->net_stats;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
 * e1000_change_mtu - Change the Maximum Transfer Unit
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
 * @netdev: network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
 * @new_mtu: new value for maximum frame size
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
 * Returns 0 on success, negative on failure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
		return -EBUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		return -EINVAL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	/* Adapter-specific max frame size limits. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	switch (hw->mac_type) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	case e1000_undefined ... e1000_82542_rev2_1:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
			return -EINVAL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
		msleep(1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	/* e1000_down has a dependency on max_frame_size */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	hw->max_frame_size = max_frame;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	if (netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		e1000_down(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	 * means we reserve 2 more, this pushes us to allocate from the next
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	 * larger slab size.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	 * i.e. RXBUFFER_2048 --> size-4096 slab
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	 *  fragmented skbs */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	if (max_frame <= E1000_RXBUFFER_2048)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
		adapter->rx_buffer_len = PAGE_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	/* adjust allocation if LPE protects us, and we aren't using SBP */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	if (!hw->tbi_compatibility_on &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	printk(KERN_INFO "e1000: %s changing MTU from %d to %d\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	       netdev->name, netdev->mtu, new_mtu);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	netdev->mtu = new_mtu;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	if (netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
		e1000_up(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
		e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	clear_bit(__E1000_RESETTING, &adapter->flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
 * e1000_update_stats - Update the board statistics counters
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
void e1000_update_stats(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	unsigned long flags = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	u16 phy_tmp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	 * Prevent stats update while adapter is being reset, or if the pci
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	 * connection is down.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	if (adapter->link_speed == 0)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	if (pci_channel_offline(pdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	if (!adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		spin_lock_irqsave(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	/* these counters are modified from e1000_tbi_adjust_stats,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	 * called from the interrupt context, so they must only
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	 * be written while holding adapter->stats_lock
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	adapter->stats.crcerrs += er32(CRCERRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	adapter->stats.gprc += er32(GPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	adapter->stats.gorcl += er32(GORCL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	adapter->stats.gorch += er32(GORCH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	adapter->stats.bprc += er32(BPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	adapter->stats.mprc += er32(MPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	adapter->stats.roc += er32(ROC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	adapter->stats.prc64 += er32(PRC64);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	adapter->stats.prc127 += er32(PRC127);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	adapter->stats.prc255 += er32(PRC255);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	adapter->stats.prc511 += er32(PRC511);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	adapter->stats.prc1023 += er32(PRC1023);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	adapter->stats.prc1522 += er32(PRC1522);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	adapter->stats.symerrs += er32(SYMERRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	adapter->stats.mpc += er32(MPC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	adapter->stats.scc += er32(SCC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	adapter->stats.ecol += er32(ECOL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	adapter->stats.mcc += er32(MCC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
	adapter->stats.latecol += er32(LATECOL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	adapter->stats.dc += er32(DC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->stats.sec += er32(SEC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	adapter->stats.rlec += er32(RLEC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	adapter->stats.xonrxc += er32(XONRXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	adapter->stats.xontxc += er32(XONTXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	adapter->stats.xoffrxc += er32(XOFFRXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	adapter->stats.xofftxc += er32(XOFFTXC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	adapter->stats.fcruc += er32(FCRUC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	adapter->stats.gptc += er32(GPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	adapter->stats.gotcl += er32(GOTCL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	adapter->stats.gotch += er32(GOTCH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	adapter->stats.rnbc += er32(RNBC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	adapter->stats.ruc += er32(RUC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	adapter->stats.rfc += er32(RFC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	adapter->stats.rjc += er32(RJC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	adapter->stats.torl += er32(TORL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	adapter->stats.torh += er32(TORH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
	adapter->stats.totl += er32(TOTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	adapter->stats.toth += er32(TOTH);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	adapter->stats.tpr += er32(TPR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	adapter->stats.ptc64 += er32(PTC64);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	adapter->stats.ptc127 += er32(PTC127);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	adapter->stats.ptc255 += er32(PTC255);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	adapter->stats.ptc511 += er32(PTC511);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	adapter->stats.ptc1023 += er32(PTC1023);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	adapter->stats.ptc1522 += er32(PTC1522);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	adapter->stats.mptc += er32(MPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	adapter->stats.bptc += er32(BPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	/* used for adaptive IFS */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	hw->tx_packet_delta = er32(TPT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	adapter->stats.tpt += hw->tx_packet_delta;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	hw->collision_delta = er32(COLC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	adapter->stats.colc += hw->collision_delta;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	if (hw->mac_type >= e1000_82543) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		adapter->stats.algnerrc += er32(ALGNERRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		adapter->stats.rxerrc += er32(RXERRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
		adapter->stats.tncrs += er32(TNCRS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
		adapter->stats.cexterr += er32(CEXTERR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		adapter->stats.tsctc += er32(TSCTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
		adapter->stats.tsctfc += er32(TSCTFC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	/* Fill out the OS statistics structure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	adapter->net_stats.multicast = adapter->stats.mprc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
	adapter->net_stats.collisions = adapter->stats.colc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	/* Rx Errors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	/* RLEC on some newer hardware can be incorrect so build
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	* our own version based on RUC and ROC */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		adapter->stats.crcerrs + adapter->stats.algnerrc +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
		adapter->stats.ruc + adapter->stats.roc +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		adapter->stats.cexterr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	/* Tx Errors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	if (hw->bad_tx_carr_stats_fd &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	    adapter->link_duplex == FULL_DUPLEX) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		adapter->net_stats.tx_carrier_errors = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
		adapter->stats.tncrs = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	/* Tx Dropped needs to be maintained elsewhere */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	/* Phy Stats */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	if (hw->media_type == e1000_media_type_copper) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		if ((adapter->link_speed == SPEED_1000) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
			adapter->phy_stats.idle_errors += phy_tmp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
		if ((hw->mac_type <= e1000_82546) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
		   (hw->phy_type == e1000_phy_m88) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
			adapter->phy_stats.receive_errors += phy_tmp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	/* Management Stats */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	if (hw->has_smbus) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
		adapter->stats.mgptc += er32(MGTPTC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		adapter->stats.mgprc += er32(MGTPRC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		adapter->stats.mgpdc += er32(MGTPDC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	if (!adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
void ec_poll(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		e1000_watchdog((unsigned long) adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
		adapter->ec_watchdog_jiffies = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	e1000_intr(0, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
 * e1000_intr - Interrupt Handler
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
 * @irq: interrupt number
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 * @data: pointer to a network interface device structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
static irqreturn_t e1000_intr(int irq, void *data)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	struct net_device *netdev = data;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	u32 icr = er32(ICR);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
		return IRQ_NONE;  /* Not our interrupt */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
    if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		hw->get_link_status = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
		/* guard against interrupt when we're going down */
2214
f55fe046b22b Avoided enabling timer.
Florian Pose <fp@igh-essen.com>
parents: 2199
diff changeset
  3447
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
2199
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		int i, ec_work_done = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		for (i = 0; i < E1000_MAX_INTR; i++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
							&ec_work_done, 100) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		/* disable interrupts, without the synchronize_irq bit */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
		ew32(IMC, ~0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		E1000_WRITE_FLUSH();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		if (likely(napi_schedule_prep(&adapter->napi))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
			adapter->total_tx_bytes = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
			adapter->total_tx_packets = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
			adapter->total_rx_bytes = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
			adapter->total_rx_packets = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
			__napi_schedule(&adapter->napi);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			/* this really should not happen! if it does it is basically a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
			 * bug, but not a hard error, so enable ints and continue */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
			if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
				e1000_irq_enable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	return IRQ_HANDLED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
 * e1000_clean - NAPI Rx polling callback
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
 * EtherCAT: never called
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
static int e1000_clean(struct napi_struct *napi, int budget)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	int tx_clean_complete = 0, work_done = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	if (!tx_clean_complete)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		work_done = budget;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	/* If budget not fully consumed, exit the polling mode */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	if (work_done < budget) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		if (likely(adapter->itr_setting & 3))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
			e1000_set_itr(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
		napi_complete(napi);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
		if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
			e1000_irq_enable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	return work_done;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
			       struct e1000_tx_ring *tx_ring)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	struct e1000_tx_desc *tx_desc, *eop_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	unsigned int i, eop;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	unsigned int count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	unsigned int total_tx_bytes=0, total_tx_packets=0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	i = tx_ring->next_to_clean;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	eop = tx_ring->buffer_info[i].next_to_watch;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	       (count < tx_ring->count)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		bool cleaned = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		for ( ; !cleaned; count++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
			tx_desc = E1000_TX_DESC(*tx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
			buffer_info = &tx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
			cleaned = (i == eop);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
			if (cleaned) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
				struct sk_buff *skb = buffer_info->skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
				unsigned int segs, bytecount;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
				segs = skb_shinfo(skb)->gso_segs ?: 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
				/* multiply data chunks by size of headers */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
				bytecount = ((segs - 1) * skb_headlen(skb)) +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
				            skb->len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
				total_tx_packets += segs;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
				total_tx_bytes += bytecount;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
			tx_desc->upper.data = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
			if (unlikely(++i == tx_ring->count)) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		eop = tx_ring->buffer_info[i].next_to_watch;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	tx_ring->next_to_clean = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
#define TX_WAKE_THRESHOLD 32
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		/* Make sure that anybody stopping the queue after this
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		 * sees the new next_to_clean.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		smp_mb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		if (netif_queue_stopped(netdev) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
			netif_wake_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
			++adapter->restart_queue;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	if (!adapter->ecdev && adapter->detect_tx_hung) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		/* Detect a transmit hang in hardware, this serializes the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		 * check with the clearing of time_stamp and movement of i */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		adapter->detect_tx_hung = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		if (tx_ring->buffer_info[eop].time_stamp &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		               (adapter->tx_timeout_factor * HZ))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
			/* detected Tx unit hang */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
					"  Tx Queue             <%lu>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
					"  TDH                  <%x>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
					"  TDT                  <%x>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
					"  next_to_use          <%x>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
					"  next_to_clean        <%x>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
					"buffer_info[next_to_clean]\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
					"  time_stamp           <%lx>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
					"  next_to_watch        <%x>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
					"  jiffies              <%lx>\n"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
					"  next_to_watch.status <%x>\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
				(unsigned long)((tx_ring - adapter->tx_ring) /
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
					sizeof(struct e1000_tx_ring)),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
				readl(hw->hw_addr + tx_ring->tdh),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
				readl(hw->hw_addr + tx_ring->tdt),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
				tx_ring->next_to_use,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
				tx_ring->next_to_clean,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
				tx_ring->buffer_info[eop].time_stamp,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
				eop,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
				jiffies,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
				eop_desc->upper.fields.status);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
			netif_stop_queue(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	adapter->total_tx_bytes += total_tx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	adapter->total_tx_packets += total_tx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	adapter->net_stats.tx_bytes += total_tx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	adapter->net_stats.tx_packets += total_tx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	return (count < tx_ring->count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
 * e1000_rx_checksum - Receive Checksum Offload for 82543
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
 * @adapter:     board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
 * @status_err:  receive descriptor status and error fields
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
 * @csum:        receive descriptor csum field
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
 * @sk_buff:     socket buffer with received data
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
			      u32 csum, struct sk_buff *skb)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	u16 status = (u16)status_err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	u8 errors = (u8)(status_err >> 24);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	skb->ip_summed = CHECKSUM_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	/* 82543 or newer only */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	if (unlikely(hw->mac_type < e1000_82543)) return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	/* Ignore Checksum bit is set */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	/* TCP/UDP checksum error bit is set */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		/* let the stack verify checksum errors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
		adapter->hw_csum_err++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	/* TCP/UDP Checksum has not been calculated */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	if (!(status & E1000_RXD_STAT_TCPCS))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	/* It must be a TCP or UDP packet with a valid checksum */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		/* TCP checksum is good */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		skb->ip_summed = CHECKSUM_UNNECESSARY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	adapter->hw_csum_good++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
 * e1000_consume_page - helper function
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
                               u16 length)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	bi->page = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	skb->len += length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	skb->data_len += length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	skb->truesize += length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
 * e1000_receive_skb - helper function to handle rx indications
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
 * @status: descriptor status field as written by hardware
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
 * @skb: pointer to sk_buff to be indicated to stack
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
			      __le16 vlan, struct sk_buff *skb)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
		                         le16_to_cpu(vlan) &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
		                         E1000_RXD_SPC_VLAN_MASK);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
		netif_receive_skb(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
 * @rx_ring: ring to clean
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
 * @work_done: amount of napi work completed this call
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
 * @work_to_do: max amount of work allowed for this call to do
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
 * the return value indicates whether actual cleaning was done, there
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
 * is no guarantee that everything was cleaned
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
				     struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
				     int *work_done, int work_to_do)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	struct e1000_rx_desc *rx_desc, *next_rxd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	struct e1000_buffer *buffer_info, *next_buffer;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	unsigned long irq_flags;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	u32 length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	int cleaned_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	bool cleaned = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	unsigned int total_rx_bytes=0, total_rx_packets=0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	i = rx_ring->next_to_clean;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	rx_desc = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
	while (rx_desc->status & E1000_RXD_STAT_DD) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
		struct sk_buff *skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		u8 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
		if (*work_done >= work_to_do)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
		(*work_done)++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
		status = rx_desc->status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		skb = buffer_info->skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		if (!adapter->ecdev) buffer_info->skb = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		if (++i == rx_ring->count) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		next_rxd = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		prefetch(next_rxd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
		next_buffer = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		cleaned = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		cleaned_count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		               PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		buffer_info->dma = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
		length = le16_to_cpu(rx_desc->length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		/* errors is only valid for DD + EOP descriptors */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		if (!adapter->ecdev &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		    unlikely((status & E1000_RXD_STAT_EOP) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
			u8 last_byte = *(skb->data + length - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
				       last_byte)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
				spin_lock_irqsave(&adapter->stats_lock,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
				                  irq_flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
				e1000_tbi_adjust_stats(hw, &adapter->stats,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
				                       length, skb->data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
				spin_unlock_irqrestore(&adapter->stats_lock,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
				                       irq_flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
				length--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
				/* recycle both page and skb */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
				buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
				/* an error means any chain goes out the window
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
				 * too */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
				if (rx_ring->rx_skb_top)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
					dev_kfree_skb(rx_ring->rx_skb_top);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
				rx_ring->rx_skb_top = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
				goto next_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
#define rxtop rx_ring->rx_skb_top
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		if (!(status & E1000_RXD_STAT_EOP)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
			/* this descriptor is only the beginning (or middle) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
			if (!rxtop) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
				/* this is the beginning of a chain */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
				rxtop = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
				                   0, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
				/* this is the middle of a chain */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
				skb_fill_page_desc(rxtop,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
				    skb_shinfo(rxtop)->nr_frags,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
				    buffer_info->page, 0, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
				/* re-use the skb, only consumed the page */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
				buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
			e1000_consume_page(buffer_info, rxtop, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
			goto next_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
			if (rxtop) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
				/* end of the chain */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
				skb_fill_page_desc(rxtop,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
				    skb_shinfo(rxtop)->nr_frags,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
				    buffer_info->page, 0, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
				/* re-use the current skb, we only consumed the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
				 * page */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
				buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
				skb = rxtop;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
				rxtop = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
				e1000_consume_page(buffer_info, skb, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
				/* no chain, got EOP, this buf is the packet
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
				 * copybreak to save the put_page/alloc_page */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
				if (length <= copybreak &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
				    skb_tailroom(skb) >= length) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
					u8 *vaddr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
					vaddr = kmap_atomic(buffer_info->page,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
					                    KM_SKB_DATA_SOFTIRQ);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
					memcpy(skb_tail_pointer(skb), vaddr, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
					kunmap_atomic(vaddr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
					              KM_SKB_DATA_SOFTIRQ);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
					/* re-use the page, so don't erase
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
					 * buffer_info->page */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
					skb_put(skb, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
				} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
					skb_fill_page_desc(skb, 0,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
					                   buffer_info->page, 0,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
				                           length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
					e1000_consume_page(buffer_info, skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
					                   length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
		e1000_rx_checksum(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		                  (u32)(status) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
		                  ((u32)(rx_desc->errors) << 24),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		                  le16_to_cpu(rx_desc->csum), skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		pskb_trim(skb, skb->len - 4);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		/* probably a little skewed due to removing CRC */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
		total_rx_bytes += skb->len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		total_rx_packets++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		/* eth type trans needs skb->data to point to something */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
		if (!pskb_may_pull(skb, ETH_HLEN)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
			DPRINTK(DRV, ERR, "pskb_may_pull failed.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
			if (!adapter->ecdev) dev_kfree_skb(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
			goto next_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
		if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
			ecdev_receive(adapter->ecdev, skb->data, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
			// No need to detect link status as
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
			// long as frames are received: Reset watchdog.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
			adapter->ec_watchdog_jiffies = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
			skb->protocol = eth_type_trans(skb, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
next_desc:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		rx_desc->status = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		/* return some buffers to hardware, one at a time is too slow */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
			cleaned_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		/* use prefetched values */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		rx_desc = next_rxd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
		buffer_info = next_buffer;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	rx_ring->next_to_clean = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	if (cleaned_count)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	adapter->total_rx_packets += total_rx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	adapter->total_rx_bytes += total_rx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	adapter->net_stats.rx_bytes += total_rx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	adapter->net_stats.rx_packets += total_rx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	return cleaned;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
 * @adapter: board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
 * @rx_ring: ring to clean
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
 * @work_done: amount of napi work completed this call
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
 * @work_to_do: max amount of work allowed for this call to do
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
			       struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
			       int *work_done, int work_to_do)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	struct e1000_rx_desc *rx_desc, *next_rxd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
	struct e1000_buffer *buffer_info, *next_buffer;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	unsigned long flags;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	u32 length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	int cleaned_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	bool cleaned = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	unsigned int total_rx_bytes=0, total_rx_packets=0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
	i = rx_ring->next_to_clean;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	rx_desc = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	while (rx_desc->status & E1000_RXD_STAT_DD) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
		struct sk_buff *skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		u8 status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		if (*work_done >= work_to_do)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		(*work_done)++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		status = rx_desc->status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		skb = buffer_info->skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		if (!adapter->ecdev) buffer_info->skb = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		prefetch(skb->data - NET_IP_ALIGN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		if (++i == rx_ring->count) i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		next_rxd = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		prefetch(next_rxd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		next_buffer = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		cleaned = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		cleaned_count++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		pci_unmap_single(pdev, buffer_info->dma, buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		                 PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		buffer_info->dma = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		length = le16_to_cpu(rx_desc->length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		/* !EOP means multiple descriptors were used to store a single
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		 * packet, if thats the case we need to toss it.  In fact, we
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		 * to toss every packet with the EOP bit clear and the next
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		 * frame that _does_ have the EOP bit set, as it is by
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		 * definition only a frame fragment
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
			adapter->discarding = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
		if (adapter->discarding) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
			/* All receives must fit into a single buffer */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
			E1000_DBG("%s: Receive packet consumed multiple"
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
				  " buffers\n", netdev->name);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
			/* recycle */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
			buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
			if (status & E1000_RXD_STAT_EOP)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
				adapter->discarding = false;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
			goto next_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
		if (!adapter->ecdev &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		    unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
			u8 last_byte = *(skb->data + length - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
				       last_byte)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
				spin_lock_irqsave(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
				e1000_tbi_adjust_stats(hw, &adapter->stats,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
				                       length, skb->data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
				spin_unlock_irqrestore(&adapter->stats_lock,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
				                       flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
				length--;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
			} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
				/* recycle */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
				buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
				goto next_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		/* adjust length to remove Ethernet CRC, this must be
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		 * done after the TBI_ACCEPT workaround above */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
		length -= 4;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		/* probably a little skewed due to removing CRC */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		total_rx_bytes += length;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		total_rx_packets++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		/* code added for copybreak, this should improve
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		 * performance for small packets with large amounts
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		 * of reassembly being done in the stack */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		if (!adapter->ecdev && length < copybreak) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
			struct sk_buff *new_skb =
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
			if (new_skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
				skb_reserve(new_skb, NET_IP_ALIGN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
				skb_copy_to_linear_data_offset(new_skb,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
							       -NET_IP_ALIGN,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
							       (skb->data -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
							        NET_IP_ALIGN),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
							       (length +
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
							        NET_IP_ALIGN));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
				/* save the skb in buffer_info as good */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
				buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
				skb = new_skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
			/* else just continue with the old one */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		/* end copybreak code */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
		skb_put(skb, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		/* Receive Checksum Offload */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		e1000_rx_checksum(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
				  (u32)(status) |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
				  ((u32)(rx_desc->errors) << 24),
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
				  le16_to_cpu(rx_desc->csum), skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		if (adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
			ecdev_receive(adapter->ecdev, skb->data, length);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
			// No need to detect link status as
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
			// long as frames are received: Reset watchdog.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			adapter->ec_watchdog_jiffies = jiffies;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
			skb->protocol = eth_type_trans(skb, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
next_desc:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		rx_desc->status = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		/* return some buffers to hardware, one at a time is too slow */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
			cleaned_count = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		/* use prefetched values */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
		rx_desc = next_rxd;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		buffer_info = next_buffer;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	rx_ring->next_to_clean = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	if (cleaned_count)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	adapter->total_rx_packets += total_rx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	adapter->total_rx_bytes += total_rx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	adapter->net_stats.rx_bytes += total_rx_bytes;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	adapter->net_stats.rx_packets += total_rx_packets;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	return cleaned;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
 * @adapter: address of board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
 * @rx_ring: pointer to receive ring structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
 * @cleaned_count: number of buffers to allocate this pass
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
static void
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
	struct e1000_rx_desc *rx_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	struct sk_buff *skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	unsigned int bufsz = 256 -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	                     16 /*for skb_reserve */ -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	                     NET_IP_ALIGN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	i = rx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
	buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	while (cleaned_count--) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		skb = buffer_info->skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		if (skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
			skb_trim(skb, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
			goto check_page;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
		skb = netdev_alloc_skb(netdev, bufsz);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		if (unlikely(!skb)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
			/* Better luck next round */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
			adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
		/* Fix for errata 23, can't cross 64kB boundary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
			struct sk_buff *oldskb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
			DPRINTK(PROBE, ERR, "skb align check failed: %u bytes "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
					     "at %p\n", bufsz, skb->data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
			/* Try again, without freeing the previous */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
			skb = netdev_alloc_skb(netdev, bufsz);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
			/* Failed allocation, critical failure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
			if (!skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
				dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
				adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
				/* give up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
				dev_kfree_skb(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
				dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
				break; /* while (cleaned_count--) */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			/* Use new allocation */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
			dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
		/* Make buffer alignment 2 beyond a 16 byte boundary
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
		 * this will result in a 16 byte aligned IP header after
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		 * the 14 byte MAC header is removed
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
		skb_reserve(skb, NET_IP_ALIGN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
		buffer_info->length = adapter->rx_buffer_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
check_page:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
		/* allocate a new page if necessary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
		if (!buffer_info->page) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
			buffer_info->page = alloc_page(GFP_ATOMIC);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
			if (unlikely(!buffer_info->page)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
				adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		if (!buffer_info->dma)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
			buffer_info->dma = pci_map_page(pdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
			                                buffer_info->page, 0,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
			                                buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
			                                PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		rx_desc = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		if (unlikely(++i == rx_ring->count))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
		buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	if (likely(rx_ring->next_to_use != i)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
		rx_ring->next_to_use = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
		if (unlikely(i-- == 0))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
			i = (rx_ring->count - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		/* Force memory writes to complete before letting h/w
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
		 * know there are new descriptors to fetch.  (Only
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
		 * applicable for weak-ordered memory model archs,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		 * such as IA-64). */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		wmb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
 * @adapter: address of board private structure
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
				   struct e1000_rx_ring *rx_ring,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
				   int cleaned_count)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
	struct net_device *netdev = adapter->netdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	struct pci_dev *pdev = adapter->pdev;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	struct e1000_rx_desc *rx_desc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	struct e1000_buffer *buffer_info;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	struct sk_buff *skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
	unsigned int i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
	i = rx_ring->next_to_use;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
	while (cleaned_count--) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		skb = buffer_info->skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		if (skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
			skb_trim(skb, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
			goto map_skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
		skb = netdev_alloc_skb(netdev, bufsz);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		if (unlikely(!skb)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			/* Better luck next round */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
			break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
		/* Fix for errata 23, can't cross 64kB boundary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
			struct sk_buff *oldskb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
					     "at %p\n", bufsz, skb->data);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			/* Try again, without freeing the previous */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
			skb = netdev_alloc_skb(netdev, bufsz);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
			/* Failed allocation, critical failure */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			if (!skb) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
				dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
				adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
				/* give up */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
				dev_kfree_skb(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
				dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
				adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
				break; /* while !buffer_info->skb */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			/* Use new allocation */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			dev_kfree_skb(oldskb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
		/* Make buffer alignment 2 beyond a 16 byte boundary
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		 * this will result in a 16 byte aligned IP header after
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
		 * the 14 byte MAC header is removed
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
		skb_reserve(skb, NET_IP_ALIGN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		buffer_info->skb = skb;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		buffer_info->length = adapter->rx_buffer_len;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
map_skb:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		buffer_info->dma = pci_map_single(pdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
						  skb->data,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
						  buffer_info->length,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
						  PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		 * XXX if it was allocated cleanly it will never map to a
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
		 * boundary crossing
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
		 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		/* Fix for errata 23, can't cross 64kB boundary */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		if (!e1000_check_64k_bound(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
					(void *)(unsigned long)buffer_info->dma,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
					adapter->rx_buffer_len)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
			DPRINTK(RX_ERR, ERR,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
				"dma align check failed: %u bytes at %p\n",
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
				adapter->rx_buffer_len,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
				(void *)(unsigned long)buffer_info->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
			if (!adapter->ecdev) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
				dev_kfree_skb(skb);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
				buffer_info->skb = NULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
			pci_unmap_single(pdev, buffer_info->dma,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
					 adapter->rx_buffer_len,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
					 PCI_DMA_FROMDEVICE);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
			buffer_info->dma = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			adapter->alloc_rx_buff_failed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
			break; /* while !buffer_info->skb */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		rx_desc = E1000_RX_DESC(*rx_ring, i);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		if (unlikely(++i == rx_ring->count))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
			i = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
		buffer_info = &rx_ring->buffer_info[i];
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	if (likely(rx_ring->next_to_use != i)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		rx_ring->next_to_use = i;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
		if (unlikely(i-- == 0))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
			i = (rx_ring->count - 1);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		/* Force memory writes to complete before letting h/w
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
		 * know there are new descriptors to fetch.  (Only
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
		 * applicable for weak-ordered memory model archs,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
		 * such as IA-64). */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
		wmb();
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		writel(i, hw->hw_addr + rx_ring->rdt);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
 * @adapter:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
static void e1000_smartspeed(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	u16 phy_status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
	u16 phy_ctrl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	if (adapter->smartspeed == 0) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		/* If Master/Slave config fault is asserted twice,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		 * we assume back-to-back */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
					    phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			adapter->smartspeed++;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
			if (!e1000_phy_setup_autoneg(hw) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
			   !e1000_read_phy_reg(hw, PHY_CTRL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
				   	       &phy_ctrl)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
					     MII_CR_RESTART_AUTO_NEG);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
				e1000_write_phy_reg(hw, PHY_CTRL,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
						    phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
		/* If still no link, perhaps using 2/3 pair cable */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		phy_ctrl |= CR_1000T_MS_ENABLE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		if (!e1000_phy_setup_autoneg(hw) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
				     MII_CR_RESTART_AUTO_NEG);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		adapter->smartspeed = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
 * e1000_ioctl -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
 * @netdev:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
 * @ifreq:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
 * @cmd:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	switch (cmd) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	case SIOCGMIIPHY:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	case SIOCGMIIREG:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	case SIOCSMIIREG:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		return e1000_mii_ioctl(netdev, ifr, cmd);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		return -EOPNOTSUPP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
 * e1000_mii_ioctl -
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
 * @netdev:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
 * @ifreq:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
 * @cmd:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
 **/
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
			   int cmd)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	struct mii_ioctl_data *data = if_mii(ifr);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	int retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	u16 mii_reg;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	u16 spddplx;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	unsigned long flags;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	if (hw->media_type != e1000_media_type_copper)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		return -EOPNOTSUPP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	switch (cmd) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	case SIOCGMIIPHY:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
		data->phy_id = hw->phy_addr;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	case SIOCGMIIREG:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		if (adapter->ecdev) return -EPERM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		spin_lock_irqsave(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
				   &data->val_out)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
			return -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	case SIOCSMIIREG:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		if (adapter->ecdev) return -EPERM;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		if (data->reg_num & ~(0x1F))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
			return -EFAULT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
		mii_reg = data->val_in;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
		spin_lock_irqsave(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		if (e1000_write_phy_reg(hw, data->reg_num,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
					mii_reg)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
			return -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
		if (hw->media_type == e1000_media_type_copper) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			switch (data->reg_num) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
			case PHY_CTRL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
				if (mii_reg & MII_CR_POWER_DOWN)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
					break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
					hw->autoneg = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
					hw->autoneg_advertised = 0x2F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
				} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
					if (mii_reg & 0x40)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
						spddplx = SPEED_1000;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
					else if (mii_reg & 0x2000)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
						spddplx = SPEED_100;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
					else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
						spddplx = SPEED_10;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
					spddplx += (mii_reg & 0x100)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
						   ? DUPLEX_FULL :
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
						   DUPLEX_HALF;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
					retval = e1000_set_spd_dplx(adapter,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
								    spddplx);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
					if (retval)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
						return retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
				}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
				if (netif_running(adapter->netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
					e1000_reinit_locked(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
				else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
					e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
			case M88E1000_PHY_SPEC_CTRL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
			case M88E1000_EXT_PHY_SPEC_CTRL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
				if (e1000_phy_reset(hw))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
					return -EIO;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
		} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
			switch (data->reg_num) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
			case PHY_CTRL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
				if (mii_reg & MII_CR_POWER_DOWN)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
					break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
				if (netif_running(adapter->netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
					e1000_reinit_locked(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
				else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
					e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
				break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
			}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		return -EOPNOTSUPP;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	return E1000_SUCCESS;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
void e1000_pci_set_mwi(struct e1000_hw *hw)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
	struct e1000_adapter *adapter = hw->back;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	int ret_val = pci_set_mwi(adapter->pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
	if (ret_val)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
void e1000_pci_clear_mwi(struct e1000_hw *hw)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	struct e1000_adapter *adapter = hw->back;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	pci_clear_mwi(adapter->pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	struct e1000_adapter *adapter = hw->back;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	return pcix_get_mmrbc(adapter->pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
	struct e1000_adapter *adapter = hw->back;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	pcix_set_mmrbc(adapter->pdev, mmrbc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	outl(value, port);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
static void e1000_vlan_rx_register(struct net_device *netdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
				   struct vlan_group *grp)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	u32 ctrl, rctl;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
		e1000_irq_disable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
	adapter->vlgrp = grp;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	if (grp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
		/* enable VLAN tag insert/strip */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		ctrl |= E1000_CTRL_VME;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		/* enable VLAN receive filtering */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
		rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		rctl &= ~E1000_RCTL_CFIEN;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		if (!(netdev->flags & IFF_PROMISC))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
			rctl |= E1000_RCTL_VFE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		e1000_update_mng_vlan(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		/* disable VLAN tag insert/strip */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		ctrl &= ~E1000_CTRL_VME;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		/* disable VLAN receive filtering */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		rctl &= ~E1000_RCTL_VFE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
		ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		e1000_irq_enable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
	u32 vfta, index;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
	if ((hw->mng_cookie.status &
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	    (vid == adapter->mng_vlan_id))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	/* add VID to filter table */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	index = (vid >> 5) & 0x7F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	vfta |= (1 << (vid & 0x1F));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	e1000_write_vfta(hw, index, vfta);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	u32 vfta, index;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
		e1000_irq_disable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	if (!test_bit(__E1000_DOWN, &adapter->flags))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		e1000_irq_enable(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	/* remove VID from filter table */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	index = (vid >> 5) & 0x7F;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	vfta &= ~(1 << (vid & 0x1F));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	e1000_write_vfta(hw, index, vfta);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
static void e1000_restore_vlan(struct e1000_adapter *adapter)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	if (adapter->vlgrp) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
		u16 vid;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
			if (!vlan_group_get_device(adapter->vlgrp, vid))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
				continue;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	hw->autoneg = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	/* Fiber NICs only allow 1000 gbps Full duplex */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	if ((hw->media_type == e1000_media_type_fiber) &&
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		return -EINVAL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	switch (spddplx) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	case SPEED_10 + DUPLEX_HALF:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		hw->forced_speed_duplex = e1000_10_half;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	case SPEED_10 + DUPLEX_FULL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		hw->forced_speed_duplex = e1000_10_full;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	case SPEED_100 + DUPLEX_HALF:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		hw->forced_speed_duplex = e1000_100_half;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	case SPEED_100 + DUPLEX_FULL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		hw->forced_speed_duplex = e1000_100_full;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	case SPEED_1000 + DUPLEX_FULL:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		hw->autoneg = 1;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
		break;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	default:
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		return -EINVAL;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	u32 ctrl, ctrl_ext, rctl, status;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	u32 wufc = adapter->wol;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
#ifdef CONFIG_PM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	int retval = 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
		return -EBUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	netif_device_detach(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	if (netif_running(netdev)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		e1000_down(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
#ifdef CONFIG_PM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	retval = pci_save_state(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	if (retval)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		return retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	status = er32(STATUS);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	if (status & E1000_STATUS_LU)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		wufc &= ~E1000_WUFC_LNKC;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	if (wufc) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		e1000_setup_rctl(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
		e1000_set_rx_mode(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
		/* turn on all-multi mode if wake on multicast is enabled */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		if (wufc & E1000_WUFC_MC) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			rctl = er32(RCTL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
			rctl |= E1000_RCTL_MPE;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
			ew32(RCTL, rctl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
		if (hw->mac_type >= e1000_82540) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
			ctrl = er32(CTRL);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
			/* advertise wake from D3Cold */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
			#define E1000_CTRL_ADVD3WUC 0x00100000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
			/* phy power management enable */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
			ctrl |= E1000_CTRL_ADVD3WUC |
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
				E1000_CTRL_EN_PHY_PWR_MGMT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
			ew32(CTRL, ctrl);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		if (hw->media_type == e1000_media_type_fiber ||
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		    hw->media_type == e1000_media_type_internal_serdes) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
			/* keep the laser running in D3 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
			ctrl_ext = er32(CTRL_EXT);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
			ew32(CTRL_EXT, ctrl_ext);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		ew32(WUC, E1000_WUC_PME_EN);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		ew32(WUFC, wufc);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		ew32(WUC, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		ew32(WUFC, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
	e1000_release_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
	*enable_wake = !!wufc;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	/* make sure adapter isn't asleep if manageability is enabled */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	if (adapter->en_mng_pt)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		*enable_wake = true;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
	if (netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
		e1000_free_irq(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	pci_disable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
#ifdef CONFIG_PM
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	int retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	bool wake;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	retval = __e1000_shutdown(pdev, &wake);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	if (retval)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		return retval;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	if (wake) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		pci_prepare_to_sleep(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	} else {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
		pci_wake_from_d3(pdev, false);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
		pci_set_power_state(pdev, PCI_D3hot);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
static int e1000_resume(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	u32 err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	if (adapter->ecdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
		return -EBUSY;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	pci_set_power_state(pdev, PCI_D0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	pci_restore_state(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	if (adapter->need_ioport)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		err = pci_enable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
		err = pci_enable_device_mem(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	pci_set_master(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	pci_enable_wake(pdev, PCI_D3hot, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	pci_enable_wake(pdev, PCI_D3cold, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	if (netif_running(netdev)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
		err = e1000_request_irq(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
		if (err)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
			return err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	e1000_power_up_phy(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	ew32(WUS, ~0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	e1000_init_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	if (netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		e1000_up(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	if (!adapter->ecdev) netif_device_attach(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	return 0;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
static void e1000_shutdown(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	bool wake;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
	__e1000_shutdown(pdev, &wake);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	if (system_state == SYSTEM_POWER_OFF) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
		pci_wake_from_d3(pdev, wake);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		pci_set_power_state(pdev, PCI_D3hot);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
#ifdef CONFIG_NET_POLL_CONTROLLER
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
/*
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
 * Polling 'interrupt' - used by things like netconsole to send skbs
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
 * without having to re-enable interrupts. It's not called while
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
 * the interrupt routine is executing.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
static void e1000_netpoll(struct net_device *netdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	disable_irq(adapter->pdev->irq);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	e1000_intr(adapter->pdev->irq, netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	enable_irq(adapter->pdev->irq);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
#endif
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
 * e1000_io_error_detected - called when PCI error is detected
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
 * @pdev: Pointer to PCI device
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
 * @state: The current pci connection state
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
 * This function is called after a PCI bus error affecting
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
 * this device has been detected.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
						pci_channel_state_t state)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
	netif_device_detach(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
	if (state == pci_channel_io_perm_failure)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
		return PCI_ERS_RESULT_DISCONNECT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	if (netif_running(netdev))
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
		e1000_down(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	pci_disable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
	/* Request a slot slot reset. */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	return PCI_ERS_RESULT_NEED_RESET;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 * e1000_io_slot_reset - called after the pci bus has been reset.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 * @pdev: Pointer to PCI device
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
 * Restart the card from scratch, as if from a cold-boot. Implementation
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
 * resembles the first-half of the e1000_resume routine.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	struct e1000_hw *hw = &adapter->hw;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	int err;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
	if (adapter->need_ioport)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		err = pci_enable_device(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	else
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		err = pci_enable_device_mem(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	if (err) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		return PCI_ERS_RESULT_DISCONNECT;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	pci_set_master(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	pci_enable_wake(pdev, PCI_D3hot, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	pci_enable_wake(pdev, PCI_D3cold, 0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	e1000_reset(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
	ew32(WUS, ~0);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	return PCI_ERS_RESULT_RECOVERED;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
/**
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
 * e1000_io_resume - called when traffic can start flowing again.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
 * @pdev: Pointer to PCI device
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
 *
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
 * This callback is called when the error recovery driver tells us that
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
 * its OK to resume normal operation. Implementation resembles the
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
 * second-half of the e1000_resume routine.
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
 */
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
static void e1000_io_resume(struct pci_dev *pdev)
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
{
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
	struct net_device *netdev = pci_get_drvdata(pdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
	struct e1000_adapter *adapter = netdev_priv(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
	e1000_init_manageability(adapter);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	if (netif_running(netdev)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
		if (e1000_up(adapter)) {
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			printk("e1000: can't bring device back up after reset\n");
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
			return;
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
		}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
	netif_device_attach(netdev);
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
}
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
15babd8d4205 Added e1000 driver for 2.6.32.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
/* e1000_main.c */