devices/e1000/e1000_main-2.6.29-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 10:12:55 -0400
changeset 2625 e25af8bd3957
parent 2262 797756190ddb
child 2419 fdb85a806585
permissions -rw-r--r--
Eoe mac address now derived from unique mac.
The EoE MAC address is now derived from the NIC part of the first global
unique MAC address of the linked list of available network interfaces or
otherwise the MAC address used by the EtherCAT master. The EoE MAC address
will get the format 02:NIC:NIC:NIC:RP:RP where NIC comes from the unique MAC
address (if available) and RP is the ring position of the EoE slave.
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     2
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     5
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     9
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    13
  more details.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    14
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    18
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    21
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    26
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    28
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    31
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k3-NAPI"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    37
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    39
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    41
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    44
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    45
static struct pci_device_id e1000_pci_tbl[] = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    83
	{0,}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    84
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    85
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    87
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   106
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   128
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   129
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   130
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   131
static int e1000_set_mac(struct net_device *netdev, void *p);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   132
static irqreturn_t e1000_intr(int irq, void *data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr_msi(int irq, void *data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   140
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   141
                                   struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   142
				   int cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   143
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   144
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   145
			   int cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   146
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   147
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   148
static void e1000_tx_timeout(struct net_device *dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   149
static void e1000_reset_task(struct work_struct *work);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   150
static void e1000_smartspeed(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   151
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   152
                                       struct sk_buff *skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   153
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   154
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   155
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   156
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   157
static void e1000_restore_vlan(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   158
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   159
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   160
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   161
static int e1000_resume(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   162
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   163
static void e1000_shutdown(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   164
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   166
/* for netdump / net console */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   167
static void e1000_netpoll (struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   168
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   169
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   170
#define COPYBREAK_DEFAULT 256
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   171
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   172
module_param(copybreak, uint, 0644);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   173
MODULE_PARM_DESC(copybreak,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   174
	"Maximum size of packet that is copied to a new buffer on receive");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   175
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   176
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   177
                     pci_channel_state_t state);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   178
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   179
static void e1000_io_resume(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   180
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   181
static struct pci_error_handlers e1000_err_handler = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   182
	.error_detected = e1000_io_error_detected,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   183
	.slot_reset = e1000_io_slot_reset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   184
	.resume = e1000_io_resume,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   185
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   186
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   187
static struct pci_driver e1000_driver = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   188
	.name     = e1000_driver_name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   189
	.id_table = e1000_pci_tbl,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   190
	.probe    = e1000_probe,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   191
	.remove   = __devexit_p(e1000_remove),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   192
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   193
	/* Power Managment Hooks */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   194
	.suspend  = e1000_suspend,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   195
	.resume   = e1000_resume,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   196
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   197
	.shutdown = e1000_shutdown,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   198
	.err_handler = &e1000_err_handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   199
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   200
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   201
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   202
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   203
MODULE_LICENSE("GPL");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   204
MODULE_VERSION(DRV_VERSION);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   205
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   206
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   207
module_param(debug, int, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   208
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   209
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   210
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   211
 * e1000_init_module - Driver Registration Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   212
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   213
 * e1000_init_module is the first routine called when the driver is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   214
 * loaded. All it does is register with the PCI subsystem.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   215
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   216
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   217
static int __init e1000_init_module(void)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   218
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   219
	int ret;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   220
	printk(KERN_INFO "%s - version %s\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   221
	       e1000_driver_string, e1000_driver_version);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   222
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   223
	printk(KERN_INFO "%s\n", e1000_copyright);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   224
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   225
	ret = pci_register_driver(&e1000_driver);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   226
	if (copybreak != COPYBREAK_DEFAULT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   227
		if (copybreak == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   228
			printk(KERN_INFO "e1000: copybreak disabled\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   229
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   230
			printk(KERN_INFO "e1000: copybreak enabled for "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   231
			       "packets <= %u bytes\n", copybreak);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   232
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   233
	return ret;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   234
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   235
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   236
module_init(e1000_init_module);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   237
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   238
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   239
 * e1000_exit_module - Driver Exit Cleanup Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   240
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   241
 * e1000_exit_module is called just before the driver is removed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   242
 * from memory.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   243
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   244
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   245
static void __exit e1000_exit_module(void)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   246
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   247
	pci_unregister_driver(&e1000_driver);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   248
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   249
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   250
module_exit(e1000_exit_module);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   251
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   252
static int e1000_request_irq(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   253
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   254
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   255
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   256
	irq_handler_t handler = e1000_intr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   257
	int irq_flags = IRQF_SHARED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   258
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   259
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   260
	if (hw->mac_type >= e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   261
		adapter->have_msi = !pci_enable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   262
		if (adapter->have_msi) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   263
			handler = e1000_intr_msi;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   264
			irq_flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   265
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   266
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   267
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   268
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   269
	                  netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   270
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   271
		if (adapter->have_msi)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   272
			pci_disable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   273
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   274
		        "Unable to allocate interrupt Error: %d\n", err);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   275
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   276
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   277
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   278
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   279
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   280
static void e1000_free_irq(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   281
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   282
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   283
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   284
	free_irq(adapter->pdev->irq, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   285
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   286
	if (adapter->have_msi)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   287
		pci_disable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   288
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   289
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   290
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   291
 * e1000_irq_disable - Mask off interrupt generation on the NIC
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   292
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   293
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   294
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   295
static void e1000_irq_disable(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   296
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   297
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   298
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   299
	ew32(IMC, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   300
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   301
	synchronize_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   302
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   303
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   304
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   305
 * e1000_irq_enable - Enable default interrupt generation settings
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   306
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   307
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   308
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   309
static void e1000_irq_enable(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   310
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   311
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   312
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   313
	ew32(IMS, IMS_ENABLE_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   314
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   315
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   316
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   317
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   318
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   319
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   320
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   321
	u16 vid = hw->mng_cookie.vlan_id;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   322
	u16 old_vid = adapter->mng_vlan_id;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   323
	if (adapter->vlgrp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   324
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   325
			if (hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   326
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   327
				e1000_vlan_rx_add_vid(netdev, vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   328
				adapter->mng_vlan_id = vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   329
			} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   330
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   331
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   332
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   333
					(vid != old_vid) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   334
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   335
				e1000_vlan_rx_kill_vid(netdev, old_vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   336
		} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   337
			adapter->mng_vlan_id = vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   338
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   339
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   340
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   341
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   342
 * e1000_release_hw_control - release control of the h/w to f/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   343
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   344
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   345
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   346
 * For ASF and Pass Through versions of f/w this means that the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   347
 * driver is no longer loaded. For AMT version (only with 82573) i
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   348
 * of the f/w this means that the network i/f is closed.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   349
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   350
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   351
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   352
static void e1000_release_hw_control(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   353
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   354
	u32 ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   355
	u32 swsm;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   356
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   357
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   358
	/* Let firmware taken over control of h/w */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   359
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   360
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   361
		swsm = er32(SWSM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   362
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   363
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   364
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   365
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   366
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   367
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   368
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   369
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   370
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   371
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   372
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   373
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   374
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   375
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   376
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   377
 * e1000_get_hw_control - get control of the h/w from f/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   378
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   379
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   380
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   381
 * For ASF and Pass Through versions of f/w this means that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   382
 * the driver is loaded. For AMT version (only with 82573)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   383
 * of the f/w this means that the network i/f is open.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   384
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   385
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   386
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   387
static void e1000_get_hw_control(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   388
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   389
	u32 ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   390
	u32 swsm;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   391
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   392
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   393
	/* Let firmware know the driver has taken over */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   394
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   395
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   396
		swsm = er32(SWSM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   397
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   398
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   399
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   400
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   401
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   402
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   403
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   404
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   405
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   406
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   407
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   408
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   409
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   410
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   411
static void e1000_init_manageability(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   412
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   413
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   414
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   415
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   416
		u32 manc = er32(MANC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   417
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   418
		/* disable hardware interception of ARP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   419
		manc &= ~(E1000_MANC_ARP_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   420
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   421
		/* enable receiving management packets to the host */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   422
		/* this will probably generate destination unreachable messages
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   423
		 * from the host OS, but the packets will be handled on SMBUS */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   424
		if (hw->has_manc2h) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   425
			u32 manc2h = er32(MANC2H);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   426
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   427
			manc |= E1000_MANC_EN_MNG2HOST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   428
#define E1000_MNG2HOST_PORT_623 (1 << 5)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   429
#define E1000_MNG2HOST_PORT_664 (1 << 6)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   430
			manc2h |= E1000_MNG2HOST_PORT_623;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   431
			manc2h |= E1000_MNG2HOST_PORT_664;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   432
			ew32(MANC2H, manc2h);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   433
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   434
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   435
		ew32(MANC, manc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   436
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   437
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   438
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   439
static void e1000_release_manageability(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   440
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   441
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   442
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   443
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   444
		u32 manc = er32(MANC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   445
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   446
		/* re-enable hardware interception of ARP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   447
		manc |= E1000_MANC_ARP_EN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   448
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   449
		if (hw->has_manc2h)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   450
			manc &= ~E1000_MANC_EN_MNG2HOST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   451
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   452
		/* don't explicitly have to mess with MANC2H since
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   453
		 * MANC has an enable disable that gates MANC2H */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   454
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   455
		ew32(MANC, manc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   456
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   457
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   458
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   459
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   460
 * e1000_configure - configure the hardware for RX and TX
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   461
 * @adapter = private board structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   462
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   463
static void e1000_configure(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   464
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   465
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   466
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   467
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   468
	e1000_set_rx_mode(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   469
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   470
	e1000_restore_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   471
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   472
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   473
	e1000_configure_tx(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   474
	e1000_setup_rctl(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   475
	e1000_configure_rx(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   476
	/* call E1000_DESC_UNUSED which always leaves
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   477
	 * at least 1 descriptor unused to make sure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   478
	 * next_to_use != next_to_clean */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   479
	for (i = 0; i < adapter->num_rx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   480
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   481
		adapter->alloc_rx_buf(adapter, ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   482
		                      E1000_DESC_UNUSED(ring));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   483
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   484
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   485
	adapter->tx_queue_len = netdev->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   486
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   487
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   488
int e1000_up(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   489
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   490
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   491
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   492
	/* hardware has been reset, we need to reload some things */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   493
	e1000_configure(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   494
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   495
	clear_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   496
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   497
	napi_enable(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   498
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   499
	e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   500
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   501
	/* fire a link change interrupt to start the watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   502
	ew32(ICS, E1000_ICS_LSC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   503
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   504
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   505
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   506
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   507
 * e1000_power_up_phy - restore link in case the phy was powered down
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   508
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   509
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   510
 * The phy may be powered down to save power and turn off link when the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   511
 * driver is unloaded and wake on lan is not enabled (among others)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   512
 * *** this routine MUST be followed by a call to e1000_reset ***
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   513
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   514
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   515
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   516
void e1000_power_up_phy(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   517
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   518
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   519
	u16 mii_reg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   520
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   521
	/* Just clear the power down bit to wake the phy back up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   522
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   523
		/* according to the manual, the phy will retain its
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   524
		 * settings across a power-down/up cycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   525
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   526
		mii_reg &= ~MII_CR_POWER_DOWN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   527
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   528
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   529
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   530
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   531
static void e1000_power_down_phy(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   532
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   533
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   534
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   535
	/* Power down the PHY so no link is implied when interface is down *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   536
	 * The PHY cannot be powered down if any of the following is true *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   537
	 * (a) WoL is enabled
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   538
	 * (b) AMT is active
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   539
	 * (c) SoL/IDER session is active */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   540
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   541
	   hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   542
		u16 mii_reg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   543
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   544
		switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   545
		case e1000_82540:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   546
		case e1000_82545:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   547
		case e1000_82545_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   548
		case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   549
		case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   550
		case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   551
		case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   552
		case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   553
		case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   554
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   555
				goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   556
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   557
		case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   558
		case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   559
		case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   560
		case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   561
		case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   562
			if (e1000_check_mng_mode(hw) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   563
			    e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   564
				goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   565
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   566
		default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   567
			goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   568
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   569
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   570
		mii_reg |= MII_CR_POWER_DOWN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   571
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   572
		mdelay(1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   573
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   574
out:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   575
	return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   576
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   577
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   578
void e1000_down(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   579
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   580
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   581
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   582
	/* signal that we're down so the interrupt handler does not
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   583
	 * reschedule our watchdog timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   584
	set_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   585
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   586
	napi_disable(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   587
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   588
	e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   589
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   590
	del_timer_sync(&adapter->tx_fifo_stall_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   591
	del_timer_sync(&adapter->watchdog_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   592
	del_timer_sync(&adapter->phy_info_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   593
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   594
	netdev->tx_queue_len = adapter->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   595
	adapter->link_speed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   596
	adapter->link_duplex = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   597
	netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   598
	netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   599
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   600
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   601
	e1000_clean_all_tx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   602
	e1000_clean_all_rx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   603
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   604
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   605
void e1000_reinit_locked(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   606
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   607
	WARN_ON(in_interrupt());
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   608
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   609
		msleep(1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   610
	e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   611
	e1000_up(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   612
	clear_bit(__E1000_RESETTING, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   613
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   614
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   615
void e1000_reset(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   616
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   617
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   618
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   619
	u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   620
	bool legacy_pba_adjust = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   621
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   622
	/* Repartition Pba for greater than 9k mtu
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   623
	 * To take effect CTRL.RST is required.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   624
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   625
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   626
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   627
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   628
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   629
	case e1000_82543:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   630
	case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   631
	case e1000_82540:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   632
	case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   633
	case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   634
		legacy_pba_adjust = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   635
		pba = E1000_PBA_48K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   636
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   637
	case e1000_82545:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   638
	case e1000_82545_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   639
	case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   640
	case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   641
		pba = E1000_PBA_48K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   642
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   643
	case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   644
	case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   645
		legacy_pba_adjust = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   646
		pba = E1000_PBA_30K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   647
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   648
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   649
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   650
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   651
		pba = E1000_PBA_38K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   652
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   653
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   654
		pba = E1000_PBA_20K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   655
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   656
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   657
		pba = E1000_PBA_8K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   658
	case e1000_undefined:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   659
	case e1000_num_macs:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   660
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   661
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   662
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   663
	if (legacy_pba_adjust) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   664
		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   665
			pba -= 8; /* allocate more FIFO for Tx */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   666
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   667
		if (hw->mac_type == e1000_82547) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   668
			adapter->tx_fifo_head = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   669
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   670
			adapter->tx_fifo_size =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   671
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   672
			atomic_set(&adapter->tx_fifo_stall, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   673
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   674
	} else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   675
		/* adjust PBA for jumbo frames */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   676
		ew32(PBA, pba);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   677
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   678
		/* To maintain wire speed transmits, the Tx FIFO should be
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   679
		 * large enough to accomodate two full transmit packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   680
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   681
		 * the Rx FIFO should be large enough to accomodate at least
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   682
		 * one full receive packet and is similarly rounded up and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   683
		 * expressed in KB. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   684
		pba = er32(PBA);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   685
		/* upper 16 bits has Tx packet buffer allocation size in KB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   686
		tx_space = pba >> 16;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   687
		/* lower 16 bits has Rx packet buffer allocation size in KB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   688
		pba &= 0xffff;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   689
		/* don't include ethernet FCS because hardware appends/strips */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   690
		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   691
		               VLAN_TAG_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   692
		min_tx_space = min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   693
		min_tx_space *= 2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   694
		min_tx_space = ALIGN(min_tx_space, 1024);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   695
		min_tx_space >>= 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   696
		min_rx_space = ALIGN(min_rx_space, 1024);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   697
		min_rx_space >>= 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   698
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   699
		/* If current Tx allocation is less than the min Tx FIFO size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   700
		 * and the min Tx FIFO size is less than the current Rx FIFO
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   701
		 * allocation, take space away from current Rx allocation */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   702
		if (tx_space < min_tx_space &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   703
		    ((min_tx_space - tx_space) < pba)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   704
			pba = pba - (min_tx_space - tx_space);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   705
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   706
			/* PCI/PCIx hardware has PBA alignment constraints */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   707
			switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   708
			case e1000_82545 ... e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   709
				pba &= ~(E1000_PBA_8K - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   710
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   711
			default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   712
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   713
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   714
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   715
			/* if short on rx space, rx wins and must trump tx
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   716
			 * adjustment or use Early Receive if available */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   717
			if (pba < min_rx_space) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   718
				switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   719
				case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   720
					/* ERT enabled in e1000_configure_rx */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   721
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   722
				default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   723
					pba = min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   724
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   725
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   726
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   727
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   728
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   729
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   730
	ew32(PBA, pba);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   731
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   732
	/* flow control settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   733
	/* Set the FC high water mark to 90% of the FIFO size.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   734
	 * Required to clear last 3 LSB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   735
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   736
	/* We can't use 90% on small FIFOs because the remainder
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   737
	 * would be less than 1 full frame.  In this case, we size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   738
	 * it to allow at least a full frame above the high water
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   739
	 *  mark. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   740
	if (pba < E1000_PBA_16K)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   741
		fc_high_water_mark = (pba * 1024) - 1600;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   742
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   743
	hw->fc_high_water = fc_high_water_mark;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   744
	hw->fc_low_water = fc_high_water_mark - 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   745
	if (hw->mac_type == e1000_80003es2lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   746
		hw->fc_pause_time = 0xFFFF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   747
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   748
		hw->fc_pause_time = E1000_FC_PAUSE_TIME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   749
	hw->fc_send_xon = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   750
	hw->fc = hw->original_fc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   751
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   752
	/* Allow time for pending master requests to run */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   753
	e1000_reset_hw(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   754
	if (hw->mac_type >= e1000_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   755
		ew32(WUC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   756
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   757
	if (e1000_init_hw(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   758
		DPRINTK(PROBE, ERR, "Hardware Error\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   759
	e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   760
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   761
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   762
	if (hw->mac_type >= e1000_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   763
	    hw->mac_type <= e1000_82547_rev_2 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   764
	    hw->autoneg == 1 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   765
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   766
		u32 ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   767
		/* clear phy power management bit if we are in gig only mode,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   768
		 * which if enabled will attempt negotiation to 100Mb, which
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   769
		 * can cause a loss of link at power off or driver unload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   770
		ctrl &= ~E1000_CTRL_SWDPIN3;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   771
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   772
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   773
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   774
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   775
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   776
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   777
	e1000_reset_adaptive(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   778
	e1000_phy_get_info(hw, &adapter->phy_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   779
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   780
	if (!adapter->smart_power_down &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   781
	    (hw->mac_type == e1000_82571 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   782
	     hw->mac_type == e1000_82572)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   783
		u16 phy_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   784
		/* speed up time to link by disabling smart power down, ignore
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   785
		 * the return value of this function because there is nothing
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   786
		 * different we would do if it failed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   787
		e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   788
		                   &phy_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   789
		phy_data &= ~IGP02E1000_PM_SPD;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   790
		e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   791
		                    phy_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   792
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   793
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   794
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   795
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   796
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   797
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   798
 *  Dump the eeprom for users having checksum issues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   799
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   800
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   801
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   802
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   803
	struct ethtool_eeprom eeprom;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   804
	const struct ethtool_ops *ops = netdev->ethtool_ops;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   805
	u8 *data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   806
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   807
	u16 csum_old, csum_new = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   808
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   809
	eeprom.len = ops->get_eeprom_len(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   810
	eeprom.offset = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   811
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   812
	data = kmalloc(eeprom.len, GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   813
	if (!data) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   814
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   815
		       " data\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   816
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   817
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   818
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   819
	ops->get_eeprom(netdev, &eeprom, data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   820
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   821
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   822
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   823
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   824
		csum_new += data[i] + (data[i + 1] << 8);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   825
	csum_new = EEPROM_SUM - csum_new;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   826
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   827
	printk(KERN_ERR "/*********************/\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   828
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   829
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   830
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   831
	printk(KERN_ERR "Offset    Values\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   832
	printk(KERN_ERR "========  ======\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   833
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   834
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   835
	printk(KERN_ERR "Include this output when contacting your support "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   836
	       "provider.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   837
	printk(KERN_ERR "This is not a software error! Something bad "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   838
	       "happened to your hardware or\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   839
	printk(KERN_ERR "EEPROM image. Ignoring this "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   840
	       "problem could result in further problems,\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   841
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   842
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   843
	       "which is invalid\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   844
	printk(KERN_ERR "and requires you to set the proper MAC "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   845
	       "address manually before continuing\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   846
	printk(KERN_ERR "to enable this network device.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   847
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   848
	       "to your hardware vendor\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   849
	printk(KERN_ERR "or Intel Customer Support.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   850
	printk(KERN_ERR "/*********************/\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   851
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   852
	kfree(data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   853
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   854
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   855
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   856
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   857
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   858
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   859
 * Return true if an adapter needs ioport resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   860
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   861
static int e1000_is_need_ioport(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   862
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   863
	switch (pdev->device) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   864
	case E1000_DEV_ID_82540EM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   865
	case E1000_DEV_ID_82540EM_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   866
	case E1000_DEV_ID_82540EP:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   867
	case E1000_DEV_ID_82540EP_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   868
	case E1000_DEV_ID_82540EP_LP:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   869
	case E1000_DEV_ID_82541EI:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   870
	case E1000_DEV_ID_82541EI_MOBILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   871
	case E1000_DEV_ID_82541ER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   872
	case E1000_DEV_ID_82541ER_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   873
	case E1000_DEV_ID_82541GI:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   874
	case E1000_DEV_ID_82541GI_LF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   875
	case E1000_DEV_ID_82541GI_MOBILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   876
	case E1000_DEV_ID_82544EI_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   877
	case E1000_DEV_ID_82544EI_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   878
	case E1000_DEV_ID_82544GC_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   879
	case E1000_DEV_ID_82544GC_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   880
	case E1000_DEV_ID_82545EM_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   881
	case E1000_DEV_ID_82545EM_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   882
	case E1000_DEV_ID_82546EB_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   883
	case E1000_DEV_ID_82546EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   884
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   885
		return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   886
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   887
		return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   888
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   889
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   890
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   891
static const struct net_device_ops e1000_netdev_ops = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   892
	.ndo_open		= e1000_open,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   893
	.ndo_stop		= e1000_close,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   894
	.ndo_start_xmit		= e1000_xmit_frame,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   895
	.ndo_get_stats		= e1000_get_stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   896
	.ndo_set_rx_mode	= e1000_set_rx_mode,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   897
	.ndo_set_mac_address	= e1000_set_mac,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   898
	.ndo_tx_timeout 	= e1000_tx_timeout,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   899
	.ndo_change_mtu		= e1000_change_mtu,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   900
	.ndo_do_ioctl		= e1000_ioctl,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   901
	.ndo_validate_addr	= eth_validate_addr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   902
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   903
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   904
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   905
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   906
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   907
	.ndo_poll_controller	= e1000_netpoll,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   908
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   909
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   910
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   911
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   912
 * e1000_probe - Device Initialization Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   913
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   914
 * @ent: entry in e1000_pci_tbl
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   915
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   916
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   917
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   918
 * e1000_probe initializes an adapter identified by a pci_dev structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   919
 * The OS initialization, configuring of the adapter private structure,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   920
 * and a hardware reset occur.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   921
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   922
static int __devinit e1000_probe(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   923
				 const struct pci_device_id *ent)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   924
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   925
	struct net_device *netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   926
	struct e1000_adapter *adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   927
	struct e1000_hw *hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   928
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   929
	static int cards_found = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   930
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   931
	int i, err, pci_using_dac;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   932
	u16 eeprom_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   933
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   934
	int bars, need_ioport;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   935
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   936
	/* do not allocate ioport bars when not needed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   937
	need_ioport = e1000_is_need_ioport(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   938
	if (need_ioport) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   939
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   940
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   941
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   942
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   943
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   944
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   945
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   946
		return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   947
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   948
	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   949
	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   950
		pci_using_dac = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   951
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   952
		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   953
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   954
			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   955
			if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   956
				E1000_ERR("No usable DMA configuration, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   957
					  "aborting\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   958
				goto err_dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   959
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   960
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   961
		pci_using_dac = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   962
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   963
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   964
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   965
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   966
		goto err_pci_reg;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   967
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   968
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   969
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   970
	err = -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   971
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   972
	if (!netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   973
		goto err_alloc_etherdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   974
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   975
	SET_NETDEV_DEV(netdev, &pdev->dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   976
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   977
	pci_set_drvdata(pdev, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   978
	adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   979
	adapter->netdev = netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   980
	adapter->pdev = pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   981
	adapter->msg_enable = (1 << debug) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   982
	adapter->bars = bars;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   983
	adapter->need_ioport = need_ioport;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   984
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   985
	hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   986
	hw->back = adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   987
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   988
	err = -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   989
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   990
	if (!hw->hw_addr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   991
		goto err_ioremap;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   992
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   993
	if (adapter->need_ioport) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   994
		for (i = BAR_1; i <= BAR_5; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   995
			if (pci_resource_len(pdev, i) == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   996
				continue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   997
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   998
				hw->io_base = pci_resource_start(pdev, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   999
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1000
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1001
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1002
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1003
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1004
	netdev->netdev_ops = &e1000_netdev_ops;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1005
	e1000_set_ethtool_ops(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1006
	netdev->watchdog_timeo = 5 * HZ;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1007
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1008
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1009
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1010
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1011
	adapter->bd_number = cards_found;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1012
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1013
	/* setup the private structure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1014
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1015
	err = e1000_sw_init(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1016
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1017
		goto err_sw_init;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1018
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1019
	err = -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1020
	/* Flash BAR mapping must happen after e1000_sw_init
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1021
	 * because it depends on mac_type */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1022
	if ((hw->mac_type == e1000_ich8lan) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1023
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1024
		hw->flash_address = pci_ioremap_bar(pdev, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1025
		if (!hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1026
			goto err_flashmap;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1027
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1028
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1029
	if (e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1030
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1031
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1032
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1033
		netdev->features = NETIF_F_SG |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1034
				   NETIF_F_HW_CSUM |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1035
				   NETIF_F_HW_VLAN_TX |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1036
				   NETIF_F_HW_VLAN_RX |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1037
				   NETIF_F_HW_VLAN_FILTER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1038
		if (hw->mac_type == e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1039
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1040
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1041
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1042
	if ((hw->mac_type >= e1000_82544) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1043
	   (hw->mac_type != e1000_82547))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1044
		netdev->features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1045
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1046
	if (hw->mac_type > e1000_82547_rev_2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1047
		netdev->features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1048
	if (pci_using_dac)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1049
		netdev->features |= NETIF_F_HIGHDMA;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1050
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1051
	netdev->features |= NETIF_F_LLTX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1052
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1053
	netdev->vlan_features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1054
	netdev->vlan_features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1055
	netdev->vlan_features |= NETIF_F_HW_CSUM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1056
	netdev->vlan_features |= NETIF_F_SG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1057
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1058
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1059
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1060
	/* initialize eeprom parameters */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1061
	if (e1000_init_eeprom_params(hw)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1062
		E1000_ERR("EEPROM initialization failed\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1063
		goto err_eeprom;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1064
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1065
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1066
	/* before reading the EEPROM, reset the controller to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1067
	 * put the device in a known good starting state */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1068
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1069
	e1000_reset_hw(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1070
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1071
	/* make sure the EEPROM is good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1072
	if (e1000_validate_eeprom_checksum(hw) < 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1073
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1074
		e1000_dump_eeprom(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1075
		/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1076
		 * set MAC address to all zeroes to invalidate and temporary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1077
		 * disable this device for the user. This blocks regular
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1078
		 * traffic while still permitting ethtool ioctls from reaching
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1079
		 * the hardware as well as allowing the user to run the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1080
		 * interface after manually setting a hw addr using
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1081
		 * `ip set address`
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1082
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1083
		memset(hw->mac_addr, 0, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1084
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1085
		/* copy the MAC address out of the EEPROM */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1086
		if (e1000_read_mac_addr(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1087
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1088
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1089
	/* don't block initalization here due to bad MAC address */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1090
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1091
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1092
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1093
	if (!is_valid_ether_addr(netdev->perm_addr))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1094
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1095
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1096
	e1000_get_bus_info(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1097
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1098
	init_timer(&adapter->tx_fifo_stall_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1099
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1100
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1101
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1102
	init_timer(&adapter->watchdog_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1103
	adapter->watchdog_timer.function = &e1000_watchdog;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1104
	adapter->watchdog_timer.data = (unsigned long) adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1105
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1106
	init_timer(&adapter->phy_info_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1107
	adapter->phy_info_timer.function = &e1000_update_phy_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1108
	adapter->phy_info_timer.data = (unsigned long)adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1109
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1110
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1111
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1112
	e1000_check_options(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1113
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1114
	/* Initial Wake on LAN setting
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1115
	 * If APM wake is enabled in the EEPROM,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1116
	 * enable the ACPI Magic Packet filter
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1117
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1118
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1119
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1120
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1121
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1122
	case e1000_82543:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1123
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1124
	case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1125
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1126
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1127
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1128
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1129
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1130
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1131
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1132
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1133
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1134
	case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1135
	case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1136
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1137
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1138
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1139
			e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1140
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1141
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1142
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1143
		/* Fall Through */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1144
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1145
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1146
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1147
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1148
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1149
	if (eeprom_data & eeprom_apme_mask)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1150
		adapter->eeprom_wol |= E1000_WUFC_MAG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1151
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1152
	/* now that we have the eeprom settings, apply the special cases
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1153
	 * where the eeprom may be wrong or the board simply won't support
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1154
	 * wake on lan on a particular port */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1155
	switch (pdev->device) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1156
	case E1000_DEV_ID_82546GB_PCIE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1157
		adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1158
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1159
	case E1000_DEV_ID_82546EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1160
	case E1000_DEV_ID_82546GB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1161
	case E1000_DEV_ID_82571EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1162
		/* Wake events only supported on port A for dual fiber
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1163
		 * regardless of eeprom setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1164
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1165
			adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1166
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1167
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1168
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1169
	case E1000_DEV_ID_82571EB_QUAD_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1170
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1171
	case E1000_DEV_ID_82571PT_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1172
		/* if quad port adapter, disable WoL on all but port A */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1173
		if (global_quad_port_a != 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1174
			adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1175
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1176
			adapter->quad_port_a = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1177
		/* Reset for multiple quad port adapters */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1178
		if (++global_quad_port_a == 4)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1179
			global_quad_port_a = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1180
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1181
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1182
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1183
	/* initialize the wol settings based on the eeprom settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1184
	adapter->wol = adapter->eeprom_wol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1185
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1186
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1187
	/* print bus type/speed/width info */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1188
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1189
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1190
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1191
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1192
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1193
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1194
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1195
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1196
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1197
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1198
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1199
		 "32-bit"));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1200
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1201
	printk("%pM\n", netdev->dev_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1202
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1203
	if (hw->bus_type == e1000_bus_type_pci_express) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1204
		DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1205
			"longer be supported by this driver in the future.\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1206
			pdev->vendor, pdev->device);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1207
		DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1208
			"driver instead.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1209
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1210
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1211
	/* reset the hardware with the new settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1212
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1213
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1214
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1215
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1216
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1217
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1218
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1219
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1220
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1221
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1222
	/* tell the stack to leave us alone until e1000_open() is called */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1223
	netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1224
	netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1225
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1226
	strcpy(netdev->name, "eth%d");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1227
	err = register_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1228
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1229
		goto err_register;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1230
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1231
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1232
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1233
	cards_found++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1234
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1235
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1236
err_register:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1237
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1238
err_eeprom:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1239
	if (!e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1240
		e1000_phy_hw_reset(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1241
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1242
	if (hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1243
		iounmap(hw->flash_address);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1244
err_flashmap:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1245
	kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1246
	kfree(adapter->rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1247
err_sw_init:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1248
	iounmap(hw->hw_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1249
err_ioremap:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1250
	free_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1251
err_alloc_etherdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1252
	pci_release_selected_regions(pdev, bars);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1253
err_pci_reg:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1254
err_dma:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1255
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1256
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1257
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1258
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1259
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1260
 * e1000_remove - Device Removal Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1261
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1262
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1263
 * e1000_remove is called by the PCI subsystem to alert the driver
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1264
 * that it should release a PCI device.  The could be caused by a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1265
 * Hot-Plug event, or because the driver is going to be removed from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1266
 * memory.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1267
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1268
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1269
static void __devexit e1000_remove(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1270
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1271
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1272
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1273
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1274
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1275
	cancel_work_sync(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1276
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1277
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1278
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1279
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1280
	 * would have already happened in close and is redundant. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1281
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1282
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1283
	unregister_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1284
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1285
	if (!e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1286
		e1000_phy_hw_reset(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1287
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1288
	kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1289
	kfree(adapter->rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1290
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1291
	iounmap(hw->hw_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1292
	if (hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1293
		iounmap(hw->flash_address);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1294
	pci_release_selected_regions(pdev, adapter->bars);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1295
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1296
	free_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1297
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1298
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1299
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1300
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1301
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1302
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1303
 * @adapter: board private structure to initialize
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1304
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1305
 * e1000_sw_init initializes the Adapter private data structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1306
 * Fields are initialized based on PCI device information and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1307
 * OS network device settings (MTU size).
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1308
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1309
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1310
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1311
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1312
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1313
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1314
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1315
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1316
	/* PCI config space info */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1317
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1318
	hw->vendor_id = pdev->vendor;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1319
	hw->device_id = pdev->device;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1320
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1321
	hw->subsystem_id = pdev->subsystem_device;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1322
	hw->revision_id = pdev->revision;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1323
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1324
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1325
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1326
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1327
	hw->max_frame_size = netdev->mtu +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1328
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1329
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1330
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1331
	/* identify the MAC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1332
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1333
	if (e1000_set_mac_type(hw)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1334
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1335
		return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1336
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1337
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1338
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1339
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1340
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1341
	case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1342
	case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1343
	case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1344
	case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1345
		hw->phy_init_script = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1346
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1347
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1348
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1349
	e1000_set_media_type(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1350
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1351
	hw->wait_autoneg_complete = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1352
	hw->tbi_compatibility_en = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1353
	hw->adaptive_ifs = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1354
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1355
	/* Copper options */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1356
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1357
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1358
		hw->mdix = AUTO_ALL_MODES;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1359
		hw->disable_polarity_correction = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1360
		hw->master_slave = E1000_MASTER_SLAVE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1361
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1362
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1363
	adapter->num_tx_queues = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1364
	adapter->num_rx_queues = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1365
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1366
	if (e1000_alloc_queues(adapter)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1367
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1368
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1369
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1370
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1371
	spin_lock_init(&adapter->tx_queue_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1372
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1373
	/* Explicitly disable IRQ since the NIC can be in any state. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1374
	e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1375
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1376
	spin_lock_init(&adapter->stats_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1377
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1378
	set_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1379
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1380
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1381
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1382
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1383
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1384
 * e1000_alloc_queues - Allocate memory for all rings
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1385
 * @adapter: board private structure to initialize
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1386
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1387
 * We allocate one ring per queue at run-time since we don't know the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1388
 * number of queues at compile-time.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1389
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1390
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1391
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1392
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1393
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1394
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1395
	if (!adapter->tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1396
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1397
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1398
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1399
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1400
	if (!adapter->rx_ring) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1401
		kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1402
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1403
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1404
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1405
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1406
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1407
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1408
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1409
 * e1000_open - Called when a network interface is made active
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1410
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1411
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1412
 * Returns 0 on success, negative value on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1413
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1414
 * The open entry point is called when a network interface is made
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1415
 * active by the system (IFF_UP).  At this point all resources needed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1416
 * for transmit and receive operations are allocated, the interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1417
 * handler is registered with the OS, the watchdog timer is started,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1418
 * and the stack is notified that the interface is ready.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1419
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1420
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1421
static int e1000_open(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1422
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1423
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1424
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1425
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1426
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1427
	/* disallow open during test */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1428
	if (test_bit(__E1000_TESTING, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1429
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1430
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1431
	/* allocate transmit descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1432
	err = e1000_setup_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1433
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1434
		goto err_setup_tx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1435
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1436
	/* allocate receive descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1437
	err = e1000_setup_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1438
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1439
		goto err_setup_rx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1440
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1441
	e1000_power_up_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1442
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1443
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1444
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1445
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1446
		e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1447
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1448
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1449
	/* If AMT is enabled, let the firmware know that the network
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1450
	 * interface is now open */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1451
	if (hw->mac_type == e1000_82573 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1452
	    e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1453
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1454
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1455
	/* before we allocate an interrupt, we must be ready to handle it.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1456
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1457
	 * as soon as we call pci_request_irq, so we have to setup our
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1458
	 * clean_rx handler before we do so.  */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1459
	e1000_configure(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1460
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1461
	err = e1000_request_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1462
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1463
		goto err_req_irq;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1464
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1465
	/* From here on the code is the same as e1000_up() */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1466
	clear_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1467
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1468
	napi_enable(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1469
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1470
	e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1471
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1472
	netif_start_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1473
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1474
	/* fire a link status change interrupt to start the watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1475
	ew32(ICS, E1000_ICS_LSC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1476
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1477
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1478
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1479
err_req_irq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1480
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1481
	e1000_power_down_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1482
	e1000_free_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1483
err_setup_rx:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1484
	e1000_free_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1485
err_setup_tx:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1486
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1487
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1488
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1489
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1490
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1491
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1492
 * e1000_close - Disables a network interface
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1493
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1494
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1495
 * Returns 0, this is not allowed to fail
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1496
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1497
 * The close entry point is called when an interface is de-activated
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1498
 * by the OS.  The hardware is still under the drivers control, but
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1499
 * needs to be disabled.  A global MAC reset is issued to stop the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1500
 * hardware, and all transmit and receive resources are freed.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1501
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1502
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1503
static int e1000_close(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1504
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1505
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1506
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1507
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1508
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1509
	e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1510
	e1000_power_down_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1511
	e1000_free_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1512
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1513
	e1000_free_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1514
	e1000_free_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1515
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1516
	/* kill manageability vlan ID if supported, but not if a vlan with
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1517
	 * the same ID is registered on the host OS (let 8021q kill it) */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1518
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1519
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1520
	     !(adapter->vlgrp &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1521
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1522
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1523
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1524
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1525
	/* If AMT is enabled, let the firmware know that the network
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1526
	 * interface is now closed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1527
	if (hw->mac_type == e1000_82573 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1528
	    e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1529
		e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1530
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1531
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1532
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1533
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1534
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1535
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1536
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1537
 * @start: address of beginning of memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1538
 * @len: length of memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1539
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1540
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1541
				  unsigned long len)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1542
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1543
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1544
	unsigned long begin = (unsigned long)start;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1545
	unsigned long end = begin + len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1546
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1547
	/* First rev 82545 and 82546 need to not allow any memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1548
	 * write location to cross 64k boundary due to errata 23 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1549
	if (hw->mac_type == e1000_82545 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1550
	    hw->mac_type == e1000_82546) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1551
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1552
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1553
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1554
	return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1555
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1556
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1557
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1558
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1559
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1560
 * @txdr:    tx descriptor ring (for a specific queue) to setup
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1561
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1562
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1563
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1564
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1565
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1566
				    struct e1000_tx_ring *txdr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1567
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1568
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1569
	int size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1570
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1571
	size = sizeof(struct e1000_buffer) * txdr->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1572
	txdr->buffer_info = vmalloc(size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1573
	if (!txdr->buffer_info) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1574
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1575
		"Unable to allocate memory for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1576
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1577
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1578
	memset(txdr->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1579
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1580
	/* round up to nearest 4K */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1581
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1582
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1583
	txdr->size = ALIGN(txdr->size, 4096);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1584
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1585
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1586
	if (!txdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1587
setup_tx_desc_die:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1588
		vfree(txdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1589
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1590
		"Unable to allocate memory for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1591
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1592
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1593
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1594
	/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1595
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1596
		void *olddesc = txdr->desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1597
		dma_addr_t olddma = txdr->dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1598
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1599
				     "at %p\n", txdr->size, txdr->desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1600
		/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1601
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1602
		/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1603
		if (!txdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1604
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1605
			goto setup_tx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1606
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1607
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1608
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1609
			/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1610
			pci_free_consistent(pdev, txdr->size, txdr->desc,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1611
					    txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1612
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1613
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1614
				"Unable to allocate aligned memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1615
				"for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1616
			vfree(txdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1617
			return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1618
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1619
			/* Free old allocation, new allocation was successful */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1620
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1621
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1622
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1623
	memset(txdr->desc, 0, txdr->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1624
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1625
	txdr->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1626
	txdr->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1627
	spin_lock_init(&txdr->tx_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1628
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1629
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1630
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1631
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1632
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1633
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1634
 * 				  (Descriptors) for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1635
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1636
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1637
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1638
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1639
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1640
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1641
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1642
	int i, err = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1643
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1644
	for (i = 0; i < adapter->num_tx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1645
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1646
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1647
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1648
				"Allocation for Tx Queue %u failed\n", i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1649
			for (i-- ; i >= 0; i--)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1650
				e1000_free_tx_resources(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1651
							&adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1652
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1653
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1654
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1655
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1656
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1657
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1658
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1659
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1660
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1661
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1662
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1663
 * Configure the Tx unit of the MAC after a reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1664
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1665
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1666
static void e1000_configure_tx(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1667
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1668
	u64 tdba;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1669
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1670
	u32 tdlen, tctl, tipg, tarc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1671
	u32 ipgr1, ipgr2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1672
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1673
	/* Setup the HW Tx Head and Tail descriptor pointers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1674
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1675
	switch (adapter->num_tx_queues) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1676
	case 1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1677
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1678
		tdba = adapter->tx_ring[0].dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1679
		tdlen = adapter->tx_ring[0].count *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1680
			sizeof(struct e1000_tx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1681
		ew32(TDLEN, tdlen);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1682
		ew32(TDBAH, (tdba >> 32));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1683
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1684
		ew32(TDT, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1685
		ew32(TDH, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1686
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1687
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1688
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1689
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1690
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1691
	/* Set the default values for the Tx Inter Packet Gap timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1692
	if (hw->mac_type <= e1000_82547_rev_2 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1693
	    (hw->media_type == e1000_media_type_fiber ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1694
	     hw->media_type == e1000_media_type_internal_serdes))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1695
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1696
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1697
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1698
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1699
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1700
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1701
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1702
		tipg = DEFAULT_82542_TIPG_IPGT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1703
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1704
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1705
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1706
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1707
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1708
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1709
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1710
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1711
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1712
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1713
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1714
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1715
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1716
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1717
	ew32(TIPG, tipg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1718
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1719
	/* Set the Tx Interrupt Delay register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1720
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1721
	ew32(TIDV, adapter->tx_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1722
	if (hw->mac_type >= e1000_82540)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1723
		ew32(TADV, adapter->tx_abs_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1724
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1725
	/* Program the Transmit Control Register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1726
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1727
	tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1728
	tctl &= ~E1000_TCTL_CT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1729
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1730
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1731
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1732
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1733
		tarc = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1734
		/* set the speed mode bit, we'll clear it if we're not at
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1735
		 * gigabit link later */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1736
		tarc |= (1 << 21);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1737
		ew32(TARC0, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1738
	} else if (hw->mac_type == e1000_80003es2lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1739
		tarc = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1740
		tarc |= 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1741
		ew32(TARC0, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1742
		tarc = er32(TARC1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1743
		tarc |= 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1744
		ew32(TARC1, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1745
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1746
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1747
	e1000_config_collision_dist(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1748
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1749
	/* Setup Transmit Descriptor Settings for eop descriptor */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1750
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1751
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1752
	/* only set IDE if we are delaying interrupts using the timers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1753
	if (adapter->tx_int_delay)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1754
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1755
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1756
	if (hw->mac_type < e1000_82543)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1757
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1758
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1759
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1760
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1761
	/* Cache if we're 82544 running in PCI-X because we'll
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1762
	 * need this to apply a workaround later in the send path. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1763
	if (hw->mac_type == e1000_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1764
	    hw->bus_type == e1000_bus_type_pcix)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1765
		adapter->pcix_82544 = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1766
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1767
	ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1768
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1769
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1770
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1771
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1772
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1773
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1774
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1775
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1776
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1777
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1778
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1779
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1780
				    struct e1000_rx_ring *rxdr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1781
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1782
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1783
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1784
	int size, desc_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1785
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1786
	size = sizeof(struct e1000_buffer) * rxdr->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1787
	rxdr->buffer_info = vmalloc(size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1788
	if (!rxdr->buffer_info) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1789
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1790
		"Unable to allocate memory for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1791
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1792
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1793
	memset(rxdr->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1794
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1795
	if (hw->mac_type <= e1000_82547_rev_2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1796
		desc_len = sizeof(struct e1000_rx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1797
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1798
		desc_len = sizeof(union e1000_rx_desc_packet_split);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1799
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1800
	/* Round up to nearest 4K */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1801
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1802
	rxdr->size = rxdr->count * desc_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1803
	rxdr->size = ALIGN(rxdr->size, 4096);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1804
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1805
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1806
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1807
	if (!rxdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1808
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1809
		"Unable to allocate memory for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1810
setup_rx_desc_die:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1811
		vfree(rxdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1812
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1813
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1814
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1815
	/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1816
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1817
		void *olddesc = rxdr->desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1818
		dma_addr_t olddma = rxdr->dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1819
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1820
				     "at %p\n", rxdr->size, rxdr->desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1821
		/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1822
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1823
		/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1824
		if (!rxdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1825
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1826
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1827
				"Unable to allocate memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1828
				"for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1829
			goto setup_rx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1830
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1831
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1832
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1833
			/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1834
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1835
					    rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1836
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1837
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1838
				"Unable to allocate aligned memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1839
				"for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1840
			goto setup_rx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1841
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1842
			/* Free old allocation, new allocation was successful */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1843
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1844
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1845
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1846
	memset(rxdr->desc, 0, rxdr->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1847
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1848
	rxdr->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1849
	rxdr->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1850
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1851
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1852
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1853
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1854
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1855
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1856
 * 				  (Descriptors) for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1857
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1858
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1859
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1860
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1861
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1862
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1863
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1864
	int i, err = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1865
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1866
	for (i = 0; i < adapter->num_rx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1867
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1868
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1869
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1870
				"Allocation for Rx Queue %u failed\n", i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1871
			for (i-- ; i >= 0; i--)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1872
				e1000_free_rx_resources(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1873
							&adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1874
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1875
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1876
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1877
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1878
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1879
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1880
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1881
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1882
 * e1000_setup_rctl - configure the receive control registers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1883
 * @adapter: Board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1884
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1885
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1886
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1887
static void e1000_setup_rctl(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1888
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1889
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1890
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1891
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1892
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1893
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1894
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1895
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1896
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1897
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1898
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1899
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1900
	if (hw->tbi_compatibility_on == 1)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1901
		rctl |= E1000_RCTL_SBP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1902
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1903
		rctl &= ~E1000_RCTL_SBP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1904
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1905
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1906
		rctl &= ~E1000_RCTL_LPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1907
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1908
		rctl |= E1000_RCTL_LPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1909
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1910
	/* Setup buffer sizes */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1911
	rctl &= ~E1000_RCTL_SZ_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1912
	rctl |= E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1913
	switch (adapter->rx_buffer_len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1914
		case E1000_RXBUFFER_256:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1915
			rctl |= E1000_RCTL_SZ_256;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1916
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1917
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1918
		case E1000_RXBUFFER_512:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1919
			rctl |= E1000_RCTL_SZ_512;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1920
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1921
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1922
		case E1000_RXBUFFER_1024:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1923
			rctl |= E1000_RCTL_SZ_1024;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1924
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1925
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1926
		case E1000_RXBUFFER_2048:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1927
		default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1928
			rctl |= E1000_RCTL_SZ_2048;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1929
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1930
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1931
		case E1000_RXBUFFER_4096:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1932
			rctl |= E1000_RCTL_SZ_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1933
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1934
		case E1000_RXBUFFER_8192:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1935
			rctl |= E1000_RCTL_SZ_8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1936
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1937
		case E1000_RXBUFFER_16384:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1938
			rctl |= E1000_RCTL_SZ_16384;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1939
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1940
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1941
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1942
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1943
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1944
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1945
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1946
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1947
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1948
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1949
 * Configure the Rx unit of the MAC after a reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1950
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1951
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1952
static void e1000_configure_rx(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1953
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1954
	u64 rdba;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1955
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1956
	u32 rdlen, rctl, rxcsum, ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1957
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1958
	rdlen = adapter->rx_ring[0].count *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1959
		sizeof(struct e1000_rx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1960
	adapter->clean_rx = e1000_clean_rx_irq;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1961
	adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1962
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1963
	/* disable receives while setting up the descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1964
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1965
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1966
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1967
	/* set the Receive Delay Timer Register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1968
	ew32(RDTR, adapter->rx_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1969
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1970
	if (hw->mac_type >= e1000_82540) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1971
		ew32(RADV, adapter->rx_abs_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1972
		if (adapter->itr_setting != 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1973
			ew32(ITR, 1000000000 / (adapter->itr * 256));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1974
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1975
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1976
	if (hw->mac_type >= e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1977
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1978
		/* Reset delay timers after every interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1979
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1980
		/* Auto-Mask interrupts upon ICR access */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1981
		ctrl_ext |= E1000_CTRL_EXT_IAME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1982
		ew32(IAM, 0xffffffff);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1983
		ew32(CTRL_EXT, ctrl_ext);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1984
		E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1985
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1986
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1987
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1988
	 * the Base and Length of the Rx Descriptor Ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1989
	switch (adapter->num_rx_queues) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1990
	case 1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1991
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1992
		rdba = adapter->rx_ring[0].dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1993
		ew32(RDLEN, rdlen);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1994
		ew32(RDBAH, (rdba >> 32));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1995
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1996
		ew32(RDT, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1997
		ew32(RDH, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1998
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1999
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2000
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2001
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2002
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2003
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2004
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2005
		rxcsum = er32(RXCSUM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2006
		if (adapter->rx_csum)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2007
			rxcsum |= E1000_RXCSUM_TUOFL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2008
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2009
			/* don't need to clear IPPCSE as it defaults to 0 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2010
			rxcsum &= ~E1000_RXCSUM_TUOFL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2011
		ew32(RXCSUM, rxcsum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2012
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2013
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2014
	/* Enable Receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2015
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2016
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2017
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2018
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2019
 * e1000_free_tx_resources - Free Tx Resources per Queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2020
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2021
 * @tx_ring: Tx descriptor ring for a specific queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2022
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2023
 * Free all transmit software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2024
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2025
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2026
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2027
				    struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2028
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2029
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2030
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2031
	e1000_clean_tx_ring(adapter, tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2032
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2033
	vfree(tx_ring->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2034
	tx_ring->buffer_info = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2035
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2036
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2037
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2038
	tx_ring->desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2039
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2040
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2041
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2042
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2043
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2044
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2045
 * Free all transmit software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2046
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2047
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2048
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2049
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2050
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2051
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2052
	for (i = 0; i < adapter->num_tx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2053
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2054
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2055
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2056
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2057
					     struct e1000_buffer *buffer_info)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2058
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2059
	if (buffer_info->dma) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2060
		pci_unmap_page(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2061
				buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2062
				buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2063
				PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2064
		buffer_info->dma = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2065
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2066
	if (buffer_info->skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2067
		dev_kfree_skb_any(buffer_info->skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2068
		buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2069
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2070
	/* buffer_info must be completely set up in the transmit path */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2071
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2073
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2074
 * e1000_clean_tx_ring - Free Tx Buffers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2075
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2076
 * @tx_ring: ring to be cleaned
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2077
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2078
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2079
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2080
				struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2081
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2082
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2083
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2084
	unsigned long size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2085
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2086
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2087
	/* Free all the Tx ring sk_buffs */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2088
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2089
	for (i = 0; i < tx_ring->count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2090
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2091
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2092
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2093
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2094
	size = sizeof(struct e1000_buffer) * tx_ring->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2095
	memset(tx_ring->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2096
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2097
	/* Zero out the descriptor ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2098
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2099
	memset(tx_ring->desc, 0, tx_ring->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2100
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2101
	tx_ring->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2102
	tx_ring->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2103
	tx_ring->last_tx_tso = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2104
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2105
	writel(0, hw->hw_addr + tx_ring->tdh);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2106
	writel(0, hw->hw_addr + tx_ring->tdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2107
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2108
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2109
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2110
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2111
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2112
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2113
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2114
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2115
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2116
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2117
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2118
	for (i = 0; i < adapter->num_tx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2119
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2120
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2121
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2122
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2123
 * e1000_free_rx_resources - Free Rx Resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2124
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2125
 * @rx_ring: ring to clean the resources from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2126
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2127
 * Free all receive software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2128
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2129
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2130
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2131
				    struct e1000_rx_ring *rx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2132
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2133
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2134
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2135
	e1000_clean_rx_ring(adapter, rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2136
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2137
	vfree(rx_ring->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2138
	rx_ring->buffer_info = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2139
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2140
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2141
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2142
	rx_ring->desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2143
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2144
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2145
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2146
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2147
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2148
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2149
 * Free all receive software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2150
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2151
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2152
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2153
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2154
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2155
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2156
	for (i = 0; i < adapter->num_rx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2157
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2158
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2159
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2160
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2161
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2162
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2163
 * @rx_ring: ring to free buffers from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2164
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2165
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2166
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2167
				struct e1000_rx_ring *rx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2168
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2169
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2170
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2171
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2172
	unsigned long size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2173
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2174
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2175
	/* Free all the Rx ring sk_buffs */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2176
	for (i = 0; i < rx_ring->count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2177
		buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2178
		if (buffer_info->skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2179
			pci_unmap_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2180
					 buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2181
					 buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2182
					 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2183
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2184
			dev_kfree_skb(buffer_info->skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2185
			buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2186
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2187
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2188
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2189
	size = sizeof(struct e1000_buffer) * rx_ring->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2190
	memset(rx_ring->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2191
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2192
	/* Zero out the descriptor ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2193
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2194
	memset(rx_ring->desc, 0, rx_ring->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2195
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2196
	rx_ring->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2197
	rx_ring->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2198
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2199
	writel(0, hw->hw_addr + rx_ring->rdh);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2200
	writel(0, hw->hw_addr + rx_ring->rdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2201
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2202
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2203
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2204
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2205
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2206
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2207
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2208
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2209
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2210
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2211
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2212
	for (i = 0; i < adapter->num_rx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2213
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2214
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2215
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2216
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2217
 * and memory write and invalidate disabled for certain operations
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2218
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2219
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2220
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2221
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2222
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2223
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2224
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2225
	e1000_pci_clear_mwi(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2226
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2227
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2228
	rctl |= E1000_RCTL_RST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2229
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2230
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2231
	mdelay(5);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2232
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2233
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2234
		e1000_clean_all_rx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2235
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2236
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2237
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2238
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2239
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2240
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2241
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2242
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2243
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2244
	rctl &= ~E1000_RCTL_RST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2245
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2246
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2247
	mdelay(5);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2248
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2249
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2250
		e1000_pci_set_mwi(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2251
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2252
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2253
		/* No need to loop, because 82542 supports only 1 queue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2254
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2255
		e1000_configure_rx(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2256
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2257
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2258
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2259
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2260
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2261
 * e1000_set_mac - Change the Ethernet Address of the NIC
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2262
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2263
 * @p: pointer to an address structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2264
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2265
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2266
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2267
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2268
static int e1000_set_mac(struct net_device *netdev, void *p)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2269
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2270
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2271
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2272
	struct sockaddr *addr = p;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2273
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2274
	if (!is_valid_ether_addr(addr->sa_data))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2275
		return -EADDRNOTAVAIL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2276
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2277
	/* 82542 2.0 needs to be in reset to write receive address registers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2278
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2279
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2280
		e1000_enter_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2281
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2282
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2283
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2284
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2285
	e1000_rar_set(hw, hw->mac_addr, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2286
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2287
	/* With 82571 controllers, LAA may be overwritten (with the default)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2288
	 * due to controller reset from the other port. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2289
	if (hw->mac_type == e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2290
		/* activate the work around */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2291
		hw->laa_is_present = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2292
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2293
		/* Hold a copy of the LAA in RAR[14] This is done so that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2294
		 * between the time RAR[0] gets clobbered  and the time it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2295
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2296
		 * of the RARs and no incoming packets directed to this port
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2297
		 * are dropped. Eventaully the LAA will be in RAR[0] and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2298
		 * RAR[14] */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2299
		e1000_rar_set(hw, hw->mac_addr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2300
					E1000_RAR_ENTRIES - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2301
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2302
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2303
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2304
		e1000_leave_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2305
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2306
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2307
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2308
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2309
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2310
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2311
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2312
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2313
 * The set_rx_mode entry point is called whenever the unicast or multicast
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2314
 * address lists or the network interface flags are updated. This routine is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2315
 * responsible for configuring the hardware for proper unicast, multicast,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2316
 * promiscuous mode, and all-multi behavior.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2317
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2318
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2319
static void e1000_set_rx_mode(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2320
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2321
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2322
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2323
	struct dev_addr_list *uc_ptr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2324
	struct dev_addr_list *mc_ptr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2325
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2326
	u32 hash_value;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2327
	int i, rar_entries = E1000_RAR_ENTRIES;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2328
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2329
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2330
				E1000_NUM_MTA_REGISTERS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2331
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2332
	if (hw->mac_type == e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2333
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2334
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2335
	/* reserve RAR[14] for LAA over-write work-around */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2336
	if (hw->mac_type == e1000_82571)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2337
		rar_entries--;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2338
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2339
	/* Check for Promiscuous and All Multicast modes */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2340
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2341
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2342
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2343
	if (netdev->flags & IFF_PROMISC) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2344
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2345
		rctl &= ~E1000_RCTL_VFE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2346
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2347
		if (netdev->flags & IFF_ALLMULTI) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2348
			rctl |= E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2349
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2350
			rctl &= ~E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2351
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2352
		if (adapter->hw.mac_type != e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2353
			rctl |= E1000_RCTL_VFE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2354
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2355
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2356
	uc_ptr = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2357
	if (netdev->uc_count > rar_entries - 1) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2358
		rctl |= E1000_RCTL_UPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2359
	} else if (!(netdev->flags & IFF_PROMISC)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2360
		rctl &= ~E1000_RCTL_UPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2361
		uc_ptr = netdev->uc_list;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2362
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2363
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2364
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2365
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2366
	/* 82542 2.0 needs to be in reset to write receive address registers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2367
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2368
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2369
		e1000_enter_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2370
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2371
	/* load the first 14 addresses into the exact filters 1-14. Unicast
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2372
	 * addresses take precedence to avoid disabling unicast filtering
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2373
	 * when possible.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2374
	 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2375
	 * RAR 0 is used for the station MAC adddress
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2376
	 * if there are not 14 addresses, go ahead and clear the filters
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2377
	 * -- with 82571 controllers only 0-13 entries are filled here
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2378
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2379
	mc_ptr = netdev->mc_list;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2380
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2381
	for (i = 1; i < rar_entries; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2382
		if (uc_ptr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2383
			e1000_rar_set(hw, uc_ptr->da_addr, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2384
			uc_ptr = uc_ptr->next;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2385
		} else if (mc_ptr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2386
			e1000_rar_set(hw, mc_ptr->da_addr, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2387
			mc_ptr = mc_ptr->next;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2388
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2389
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2390
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2391
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2392
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2393
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2394
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2395
	WARN_ON(uc_ptr != NULL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2396
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2397
	/* clear the old settings from the multicast hash table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2398
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2399
	for (i = 0; i < mta_reg_count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2400
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2401
		E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2402
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2403
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2404
	/* load any remaining addresses into the hash table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2405
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2406
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2407
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2408
		e1000_mta_set(hw, hash_value);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2409
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2410
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2411
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2412
		e1000_leave_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2413
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2414
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2415
/* Need to wait a few seconds after link up to get diagnostic information from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2416
 * the phy */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2417
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2418
static void e1000_update_phy_info(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2419
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2420
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2421
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2422
	e1000_phy_get_info(hw, &adapter->phy_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2423
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2424
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2425
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2426
 * e1000_82547_tx_fifo_stall - Timer Call-back
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2427
 * @data: pointer to adapter cast into an unsigned long
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2428
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2429
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2430
static void e1000_82547_tx_fifo_stall(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2431
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2432
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2433
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2434
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2435
	u32 tctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2436
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2437
	if (atomic_read(&adapter->tx_fifo_stall)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2438
		if ((er32(TDT) == er32(TDH)) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2439
		   (er32(TDFT) == er32(TDFH)) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2440
		   (er32(TDFTS) == er32(TDFHS))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2441
			tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2442
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2443
			ew32(TDFT, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2444
			ew32(TDFH, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2445
			ew32(TDFTS, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2446
			ew32(TDFHS, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2447
			ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2448
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2449
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2450
			adapter->tx_fifo_head = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2451
			atomic_set(&adapter->tx_fifo_stall, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2452
			netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2453
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2454
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2455
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2456
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2457
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2458
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2459
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2460
 * e1000_watchdog - Timer Call-back
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2461
 * @data: pointer to adapter cast into an unsigned long
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2462
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2463
static void e1000_watchdog(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2464
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2465
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2466
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2467
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2468
	struct e1000_tx_ring *txdr = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2469
	u32 link, tctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2470
	s32 ret_val;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2471
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2472
	ret_val = e1000_check_for_link(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2473
	if ((ret_val == E1000_ERR_PHY) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2474
	    (hw->phy_type == e1000_phy_igp_3) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2475
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2476
		/* See e1000_kumeran_lock_loss_workaround() */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2477
		DPRINTK(LINK, INFO,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2478
			"Gigabit has been disabled, downgrading speed\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2479
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2480
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2481
	if (hw->mac_type == e1000_82573) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2482
		e1000_enable_tx_pkt_filtering(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2483
		if (adapter->mng_vlan_id != hw->mng_cookie.vlan_id)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2484
			e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2485
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2486
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2487
	if ((hw->media_type == e1000_media_type_internal_serdes) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2488
	   !(er32(TXCW) & E1000_TXCW_ANE))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2489
		link = !hw->serdes_link_down;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2490
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2491
		link = er32(STATUS) & E1000_STATUS_LU;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2492
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2493
	if (link) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2494
		if (!netif_carrier_ok(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2495
			u32 ctrl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2496
			bool txb2b = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2497
			e1000_get_speed_and_duplex(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2498
			                           &adapter->link_speed,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2499
			                           &adapter->link_duplex);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2500
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2501
			ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2502
			printk(KERN_INFO "e1000: %s NIC Link is Up %d Mbps %s, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2503
			       "Flow Control: %s\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2504
			       netdev->name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2505
			       adapter->link_speed,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2506
			       adapter->link_duplex == FULL_DUPLEX ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2507
			        "Full Duplex" : "Half Duplex",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2508
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2509
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2510
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2511
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2512
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2513
			/* tweak tx_queue_len according to speed/duplex
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2514
			 * and adjust the timeout factor */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2515
			netdev->tx_queue_len = adapter->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2516
			adapter->tx_timeout_factor = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2517
			switch (adapter->link_speed) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2518
			case SPEED_10:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2519
				txb2b = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2520
				netdev->tx_queue_len = 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2521
				adapter->tx_timeout_factor = 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2522
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2523
			case SPEED_100:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2524
				txb2b = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2525
				netdev->tx_queue_len = 100;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2526
				/* maybe add some timeout factor ? */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2527
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2528
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2529
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2530
			if ((hw->mac_type == e1000_82571 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2531
			     hw->mac_type == e1000_82572) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2532
			    !txb2b) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2533
				u32 tarc0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2534
				tarc0 = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2535
				tarc0 &= ~(1 << 21);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2536
				ew32(TARC0, tarc0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2537
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2538
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2539
			/* disable TSO for pcie and 10/100 speeds, to avoid
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2540
			 * some hardware issues */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2541
			if (!adapter->tso_force &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2542
			    hw->bus_type == e1000_bus_type_pci_express){
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2543
				switch (adapter->link_speed) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2544
				case SPEED_10:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2545
				case SPEED_100:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2546
					DPRINTK(PROBE,INFO,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2547
				        "10/100 speed: disabling TSO\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2548
					netdev->features &= ~NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2549
					netdev->features &= ~NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2550
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2551
				case SPEED_1000:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2552
					netdev->features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2553
					netdev->features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2554
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2555
				default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2556
					/* oops */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2557
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2558
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2559
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2560
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2561
			/* enable transmits in the hardware, need to do this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2562
			 * after setting TARC0 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2563
			tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2564
			tctl |= E1000_TCTL_EN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2565
			ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2566
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2567
			netif_carrier_on(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2568
			netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2569
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2570
			adapter->smartspeed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2571
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2572
			/* make sure the receive unit is started */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2573
			if (hw->rx_needs_kicking) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2574
				u32 rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2575
				ew32(RCTL, rctl | E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2576
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2577
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2578
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2579
		if (netif_carrier_ok(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2580
			adapter->link_speed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2581
			adapter->link_duplex = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2582
			printk(KERN_INFO "e1000: %s NIC Link is Down\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2583
			       netdev->name);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2584
			netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2585
			netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2586
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2587
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2588
			/* 80003ES2LAN workaround--
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2589
			 * For packet buffer work-around on link down event;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2590
			 * disable receives in the ISR and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2591
			 * reset device here in the watchdog
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2592
			 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2593
			if (hw->mac_type == e1000_80003es2lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2594
				/* reset device */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2595
				schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2596
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2597
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2598
		e1000_smartspeed(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2599
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2600
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2601
	e1000_update_stats(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2602
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2603
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2604
	adapter->tpt_old = adapter->stats.tpt;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2605
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2606
	adapter->colc_old = adapter->stats.colc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2607
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2608
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2609
	adapter->gorcl_old = adapter->stats.gorcl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2610
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2611
	adapter->gotcl_old = adapter->stats.gotcl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2612
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2613
	e1000_update_adaptive(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2614
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2615
	if (!netif_carrier_ok(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2616
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2617
			/* We've lost link, so the controller stops DMA,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2618
			 * but we've got queued Tx work that's never going
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2619
			 * to get done, so reset controller to flush Tx.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2620
			 * (Do the reset outside of interrupt context). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2621
			adapter->tx_timeout_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2622
			schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2623
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2624
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2625
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2626
	/* Cause software interrupt to ensure rx ring is cleaned */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2627
	ew32(ICS, E1000_ICS_RXDMT0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2628
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2629
	/* Force detection of hung controller every watchdog period */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2630
	adapter->detect_tx_hung = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2631
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2632
	/* With 82571 controllers, LAA may be overwritten due to controller
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2633
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2634
	if (hw->mac_type == e1000_82571 && hw->laa_is_present)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2635
		e1000_rar_set(hw, hw->mac_addr, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2636
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2637
	/* Reset the timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2638
	mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2639
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2640
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2641
enum latency_range {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2642
	lowest_latency = 0,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2643
	low_latency = 1,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2644
	bulk_latency = 2,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2645
	latency_invalid = 255
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2646
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2647
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2648
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2649
 * e1000_update_itr - update the dynamic ITR value based on statistics
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2650
 *      Stores a new ITR value based on packets and byte
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2651
 *      counts during the last interrupt.  The advantage of per interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2652
 *      computation is faster updates and more accurate ITR for the current
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2653
 *      traffic pattern.  Constants in this function were computed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2654
 *      based on theoretical maximum wire speed and thresholds were set based
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2655
 *      on testing data as well as attempting to minimize response time
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2656
 *      while increasing bulk throughput.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2657
 *      this functionality is controlled by the InterruptThrottleRate module
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2658
 *      parameter (see e1000_param.c)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2659
 * @adapter: pointer to adapter
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2660
 * @itr_setting: current adapter->itr
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2661
 * @packets: the number of packets during this measurement interval
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2662
 * @bytes: the number of bytes during this measurement interval
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2663
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2664
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2665
				     u16 itr_setting, int packets, int bytes)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2666
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2667
	unsigned int retval = itr_setting;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2668
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2669
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2670
	if (unlikely(hw->mac_type < e1000_82540))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2671
		goto update_itr_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2672
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2673
	if (packets == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2674
		goto update_itr_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2675
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2676
	switch (itr_setting) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2677
	case lowest_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2678
		/* jumbo frames get bulk treatment*/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2679
		if (bytes/packets > 8000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2680
			retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2681
		else if ((packets < 5) && (bytes > 512))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2682
			retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2683
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2684
	case low_latency:  /* 50 usec aka 20000 ints/s */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2685
		if (bytes > 10000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2686
			/* jumbo frames need bulk latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2687
			if (bytes/packets > 8000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2688
				retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2689
			else if ((packets < 10) || ((bytes/packets) > 1200))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2690
				retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2691
			else if ((packets > 35))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2692
				retval = lowest_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2693
		} else if (bytes/packets > 2000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2694
			retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2695
		else if (packets <= 2 && bytes < 512)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2696
			retval = lowest_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2697
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2698
	case bulk_latency: /* 250 usec aka 4000 ints/s */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2699
		if (bytes > 25000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2700
			if (packets > 35)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2701
				retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2702
		} else if (bytes < 6000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2703
			retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2704
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2705
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2706
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2707
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2708
update_itr_done:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2709
	return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2710
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2711
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2712
static void e1000_set_itr(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2713
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2714
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2715
	u16 current_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2716
	u32 new_itr = adapter->itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2717
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2718
	if (unlikely(hw->mac_type < e1000_82540))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2719
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2720
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2721
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2722
	if (unlikely(adapter->link_speed != SPEED_1000)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2723
		current_itr = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2724
		new_itr = 4000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2725
		goto set_itr_now;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2726
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2727
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2728
	adapter->tx_itr = e1000_update_itr(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2729
	                            adapter->tx_itr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2730
	                            adapter->total_tx_packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2731
	                            adapter->total_tx_bytes);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2732
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2733
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2734
		adapter->tx_itr = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2735
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2736
	adapter->rx_itr = e1000_update_itr(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2737
	                            adapter->rx_itr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2738
	                            adapter->total_rx_packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2739
	                            adapter->total_rx_bytes);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2740
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2741
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2742
		adapter->rx_itr = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2743
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2744
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2745
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2746
	switch (current_itr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2747
	/* counts and packets in update_itr are dependent on these numbers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2748
	case lowest_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2749
		new_itr = 70000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2750
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2751
	case low_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2752
		new_itr = 20000; /* aka hwitr = ~200 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2753
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2754
	case bulk_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2755
		new_itr = 4000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2756
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2757
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2758
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2759
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2760
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2761
set_itr_now:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2762
	if (new_itr != adapter->itr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2763
		/* this attempts to bias the interrupt rate towards Bulk
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2764
		 * by adding intermediate steps when interrupt rate is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2765
		 * increasing */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2766
		new_itr = new_itr > adapter->itr ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2767
		             min(adapter->itr + (new_itr >> 2), new_itr) :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2768
		             new_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2769
		adapter->itr = new_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2770
		ew32(ITR, 1000000000 / (new_itr * 256));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2771
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2772
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2773
	return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2774
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2775
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2776
#define E1000_TX_FLAGS_CSUM		0x00000001
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2777
#define E1000_TX_FLAGS_VLAN		0x00000002
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2778
#define E1000_TX_FLAGS_TSO		0x00000004
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2779
#define E1000_TX_FLAGS_IPV4		0x00000008
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2780
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2781
#define E1000_TX_FLAGS_VLAN_SHIFT	16
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2782
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2783
static int e1000_tso(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2784
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2785
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2786
	struct e1000_context_desc *context_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2787
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2788
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2789
	u32 cmd_length = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2790
	u16 ipcse = 0, tucse, mss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2791
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2792
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2793
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2794
	if (skb_is_gso(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2795
		if (skb_header_cloned(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2796
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2797
			if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2798
				return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2799
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2800
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2801
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2802
		mss = skb_shinfo(skb)->gso_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2803
		if (skb->protocol == htons(ETH_P_IP)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2804
			struct iphdr *iph = ip_hdr(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2805
			iph->tot_len = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2806
			iph->check = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2807
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2808
								 iph->daddr, 0,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2809
								 IPPROTO_TCP,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2810
								 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2811
			cmd_length = E1000_TXD_CMD_IP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2812
			ipcse = skb_transport_offset(skb) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2813
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2814
			ipv6_hdr(skb)->payload_len = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2815
			tcp_hdr(skb)->check =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2816
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2817
						 &ipv6_hdr(skb)->daddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2818
						 0, IPPROTO_TCP, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2819
			ipcse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2820
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2821
		ipcss = skb_network_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2822
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2823
		tucss = skb_transport_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2824
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2825
		tucse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2826
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2827
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2828
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2829
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2830
		i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2831
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2832
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2833
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2834
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2835
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2836
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2837
		context_desc->upper_setup.tcp_fields.tucss = tucss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2838
		context_desc->upper_setup.tcp_fields.tucso = tucso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2839
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2840
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2841
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2842
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2843
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2844
		buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2845
		buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2846
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2847
		if (++i == tx_ring->count) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2848
		tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2849
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2850
		return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2851
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2852
	return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2853
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2854
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2855
static bool e1000_tx_csum(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2856
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2857
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2858
	struct e1000_context_desc *context_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2859
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2860
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2861
	u8 css;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2862
	u32 cmd_len = E1000_TXD_CMD_DEXT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2863
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2864
	if (skb->ip_summed != CHECKSUM_PARTIAL)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2865
		return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2866
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2867
	switch (skb->protocol) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2868
	case __constant_htons(ETH_P_IP):
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2869
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2870
			cmd_len |= E1000_TXD_CMD_TCP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2871
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2872
	case __constant_htons(ETH_P_IPV6):
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2873
		/* XXX not handling all IPV6 headers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2874
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2875
			cmd_len |= E1000_TXD_CMD_TCP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2876
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2877
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2878
		if (unlikely(net_ratelimit()))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2879
			DPRINTK(DRV, WARNING,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2880
			        "checksum_partial proto=%x!\n", skb->protocol);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2881
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2882
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2883
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2884
	css = skb_transport_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2885
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2886
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2887
	buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2888
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2889
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2890
	context_desc->lower_setup.ip_config = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2891
	context_desc->upper_setup.tcp_fields.tucss = css;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2892
	context_desc->upper_setup.tcp_fields.tucso =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2893
		css + skb->csum_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2894
	context_desc->upper_setup.tcp_fields.tucse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2895
	context_desc->tcp_seg_setup.data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2896
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2897
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2898
	buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2899
	buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2900
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2901
	if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2902
	tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2903
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2904
	return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2905
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2906
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2907
#define E1000_MAX_TXD_PWR	12
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2908
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2909
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2910
static int e1000_tx_map(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2911
			struct e1000_tx_ring *tx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2912
			struct sk_buff *skb, unsigned int first,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2913
			unsigned int max_per_txd, unsigned int nr_frags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2914
			unsigned int mss)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2915
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2916
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2917
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2918
	unsigned int len = skb->len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2919
	unsigned int offset = 0, size, count = 0, i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2920
	unsigned int f;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2921
	len -= skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2922
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2923
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2924
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2925
	while (len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2926
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2927
		size = min(len, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2928
		/* Workaround for Controller erratum --
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2929
		 * descriptor for non-tso packet in a linear SKB that follows a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2930
		 * tso gets written back prematurely before the data is fully
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2931
		 * DMA'd to the controller */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2932
		if (!skb->data_len && tx_ring->last_tx_tso &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2933
		    !skb_is_gso(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2934
			tx_ring->last_tx_tso = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2935
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2936
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2937
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2938
		/* Workaround for premature desc write-backs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2939
		 * in TSO mode.  Append 4-byte sentinel desc */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2940
		if (unlikely(mss && !nr_frags && size == len && size > 8))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2941
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2942
		/* work-around for errata 10 and it applies
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2943
		 * to all controllers in PCI-X mode
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2944
		 * The fix is to make sure that the first descriptor of a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2945
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2946
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2947
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2948
		                (size > 2015) && count == 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2949
		        size = 2015;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2950
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2951
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2952
		 * terminating buffers within evenly-aligned dwords. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2953
		if (unlikely(adapter->pcix_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2954
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2955
		   size > 4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2956
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2957
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2958
		buffer_info->length = size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2959
		buffer_info->dma =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2960
			pci_map_single(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2961
				skb->data + offset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2962
				size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2963
				PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2964
		buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2965
		buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2966
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2967
		len -= size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2968
		offset += size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2969
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2970
		if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2971
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2972
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2973
	for (f = 0; f < nr_frags; f++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2974
		struct skb_frag_struct *frag;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2975
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2976
		frag = &skb_shinfo(skb)->frags[f];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2977
		len = frag->size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2978
		offset = frag->page_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2979
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2980
		while (len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2981
			buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2982
			size = min(len, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2983
			/* Workaround for premature desc write-backs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2984
			 * in TSO mode.  Append 4-byte sentinel desc */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2985
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2986
				size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2987
			/* Workaround for potential 82544 hang in PCI-X.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2988
			 * Avoid terminating buffers within evenly-aligned
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2989
			 * dwords. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2990
			if (unlikely(adapter->pcix_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2991
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2992
			   size > 4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2993
				size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2994
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2995
			buffer_info->length = size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2996
			buffer_info->dma =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2997
				pci_map_page(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2998
					frag->page,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2999
					offset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3000
					size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3001
					PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3002
			buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3003
			buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3004
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3005
			len -= size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3006
			offset += size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3007
			count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3008
			if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3009
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3010
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3011
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3012
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3013
	tx_ring->buffer_info[i].skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3014
	tx_ring->buffer_info[first].next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3015
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3016
	return count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3017
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3018
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3019
static void e1000_tx_queue(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3020
			   struct e1000_tx_ring *tx_ring, int tx_flags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3021
			   int count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3022
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3023
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3024
	struct e1000_tx_desc *tx_desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3025
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3026
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3027
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3028
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3029
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3030
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3031
		             E1000_TXD_CMD_TSE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3032
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3033
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3034
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3035
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3036
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3037
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3038
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3039
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3040
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3041
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3042
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3043
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3044
		txd_lower |= E1000_TXD_CMD_VLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3045
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3046
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3047
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3048
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3049
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3050
	while (count--) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3051
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3052
		tx_desc = E1000_TX_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3053
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3054
		tx_desc->lower.data =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3055
			cpu_to_le32(txd_lower | buffer_info->length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3056
		tx_desc->upper.data = cpu_to_le32(txd_upper);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3057
		if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3058
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3059
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3060
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3061
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3062
	/* Force memory writes to complete before letting h/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3063
	 * know there are new descriptors to fetch.  (Only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3064
	 * applicable for weak-ordered memory model archs,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3065
	 * such as IA-64). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3066
	wmb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3067
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3068
	tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3069
	writel(i, hw->hw_addr + tx_ring->tdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3070
	/* we need this if more than one processor can write to our tail
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3071
	 * at a time, it syncronizes IO on IA64/Altix systems */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3072
	mmiowb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3073
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3074
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3075
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3076
 * 82547 workaround to avoid controller hang in half-duplex environment.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3077
 * The workaround is to avoid queuing a large packet that would span
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3078
 * the internal Tx FIFO ring boundary by notifying the stack to resend
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3079
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3080
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3081
 * to the beginning of the Tx FIFO.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3082
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3083
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3084
#define E1000_FIFO_HDR			0x10
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3085
#define E1000_82547_PAD_LEN		0x3E0
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3086
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3087
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3088
				       struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3089
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3090
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3091
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3092
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3093
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3094
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3095
	if (adapter->link_duplex != HALF_DUPLEX)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3096
		goto no_fifo_stall_required;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3097
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3098
	if (atomic_read(&adapter->tx_fifo_stall))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3099
		return 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3100
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3101
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3102
		atomic_set(&adapter->tx_fifo_stall, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3103
		return 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3104
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3105
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3106
no_fifo_stall_required:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3107
	adapter->tx_fifo_head += skb_fifo_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3108
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3109
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3110
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3111
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3112
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3113
#define MINIMUM_DHCP_PACKET_SIZE 282
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3114
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3115
				    struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3116
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3117
	struct e1000_hw *hw =  &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3118
	u16 length, offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3119
	if (vlan_tx_tag_present(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3120
		if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3121
			( hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3122
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3123
			return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3124
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3125
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3126
		struct ethhdr *eth = (struct ethhdr *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3127
		if ((htons(ETH_P_IP) == eth->h_proto)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3128
			const struct iphdr *ip =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3129
				(struct iphdr *)((u8 *)skb->data+14);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3130
			if (IPPROTO_UDP == ip->protocol) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3131
				struct udphdr *udp =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3132
					(struct udphdr *)((u8 *)ip +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3133
						(ip->ihl << 2));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3134
				if (ntohs(udp->dest) == 67) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3135
					offset = (u8 *)udp + 8 - skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3136
					length = skb->len - offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3137
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3138
					return e1000_mng_write_dhcp_info(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3139
							(u8 *)udp + 8,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3140
							length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3141
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3142
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3143
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3144
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3145
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3146
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3147
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3148
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3149
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3150
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3151
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3152
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3153
	netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3154
	/* Herbert's original patch had:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3155
	 *  smp_mb__after_netif_stop_queue();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3156
	 * but since that doesn't exist yet, just open code it. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3157
	smp_mb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3158
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3159
	/* We need to check again in a case another CPU has just
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3160
	 * made room available. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3161
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3162
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3163
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3164
	/* A reprieve! */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3165
	netif_start_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3166
	++adapter->restart_queue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3167
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3168
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3169
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3170
static int e1000_maybe_stop_tx(struct net_device *netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3171
                               struct e1000_tx_ring *tx_ring, int size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3172
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3173
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3174
		return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3175
	return __e1000_maybe_stop_tx(netdev, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3176
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3177
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3178
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3179
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3180
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3181
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3182
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3183
	struct e1000_tx_ring *tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3184
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3185
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3186
	unsigned int tx_flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3187
	unsigned int len = skb->len - skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3188
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3189
	unsigned int nr_frags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3190
	unsigned int mss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3191
	int count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3192
	int tso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3193
	unsigned int f;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3194
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3195
	/* This goes back to the question of how to logically map a tx queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3196
	 * to a flow.  Right now, performance is impacted slightly negatively
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3197
	 * if using multiple tx queues.  If the stack breaks away from a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3198
	 * single qdisc implementation, we can look at this again. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3199
	tx_ring = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3200
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3201
	if (unlikely(skb->len <= 0)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3202
		dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3203
		return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3204
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3205
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3206
	/* 82571 and newer doesn't need the workaround that limited descriptor
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3207
	 * length to 4kB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3208
	if (hw->mac_type >= e1000_82571)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3209
		max_per_txd = 8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3210
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3211
	mss = skb_shinfo(skb)->gso_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3212
	/* The controller does a simple calculation to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3213
	 * make sure there is enough room in the FIFO before
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3214
	 * initiating the DMA for each buffer.  The calc is:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3215
	 * 4 = ceil(buffer len/mss).  To make sure we don't
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3216
	 * overrun the FIFO, adjust the max buffer len if mss
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3217
	 * drops. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3218
	if (mss) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3219
		u8 hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3220
		max_per_txd = min(mss << 2, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3221
		max_txd_pwr = fls(max_per_txd) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3222
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3223
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3224
		* points to just header, pull a few bytes of payload from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3225
		* frags into skb->data */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3226
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3227
		if (skb->data_len && hdr_len == len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3228
			switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3229
				unsigned int pull_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3230
			case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3231
				/* Make sure we have room to chop off 4 bytes,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3232
				 * and that the end alignment will work out to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3233
				 * this hardware's requirements
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3234
				 * NOTE: this is a TSO only workaround
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3235
				 * if end byte alignment not correct move us
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3236
				 * into the next dword */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3237
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3238
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3239
				/* fall through */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3240
			case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3241
			case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3242
			case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3243
			case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3244
				pull_size = min((unsigned int)4, skb->data_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3245
				if (!__pskb_pull_tail(skb, pull_size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3246
					DPRINTK(DRV, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3247
						"__pskb_pull_tail failed.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3248
					dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3249
					return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3250
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3251
				len = skb->len - skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3252
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3253
			default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3254
				/* do nothing */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3255
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3256
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3257
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3258
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3259
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3260
	/* reserve a descriptor for the offload context */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3261
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3262
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3263
	count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3264
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3265
	/* Controller Erratum workaround */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3266
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3267
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3268
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3269
	count += TXD_USE_COUNT(len, max_txd_pwr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3270
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3271
	if (adapter->pcix_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3272
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3273
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3274
	/* work-around for errata 10 and it applies to all controllers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3275
	 * in PCI-X mode, so add one more descriptor to the count
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3276
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3277
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3278
			(len > 2015)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3279
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3280
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3281
	nr_frags = skb_shinfo(skb)->nr_frags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3282
	for (f = 0; f < nr_frags; f++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3283
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3284
				       max_txd_pwr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3285
	if (adapter->pcix_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3286
		count += nr_frags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3287
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3288
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3289
	if (hw->tx_pkt_filtering &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3290
	    (hw->mac_type == e1000_82573))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3291
		e1000_transfer_dhcp_info(adapter, skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3292
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3293
	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3294
		/* Collision - tell upper layer to requeue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3295
		return NETDEV_TX_LOCKED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3296
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3297
	/* need: count + 2 desc gap to keep tail from touching
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3298
	 * head, otherwise try next time */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3299
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3300
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3301
		return NETDEV_TX_BUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3302
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3303
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3304
	if (unlikely(hw->mac_type == e1000_82547)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3305
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3306
			netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3307
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3308
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3309
			return NETDEV_TX_BUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3310
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3311
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3312
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3313
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3314
		tx_flags |= E1000_TX_FLAGS_VLAN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3315
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3316
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3317
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3318
	first = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3319
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3320
	tso = e1000_tso(adapter, tx_ring, skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3321
	if (tso < 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3322
		dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3323
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3324
		return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3325
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3326
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3327
	if (likely(tso)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3328
		tx_ring->last_tx_tso = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3329
		tx_flags |= E1000_TX_FLAGS_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3330
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3331
		tx_flags |= E1000_TX_FLAGS_CSUM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3332
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3333
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3334
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3335
	 * no longer assume, we must. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3336
	if (likely(skb->protocol == htons(ETH_P_IP)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3337
		tx_flags |= E1000_TX_FLAGS_IPV4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3338
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3339
	e1000_tx_queue(adapter, tx_ring, tx_flags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3340
	               e1000_tx_map(adapter, tx_ring, skb, first,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3341
	                            max_per_txd, nr_frags, mss));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3342
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3343
	netdev->trans_start = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3344
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3345
	/* Make sure there is space in the ring for the next send. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3346
	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3347
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3348
	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3349
	return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3350
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3351
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3352
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3353
 * e1000_tx_timeout - Respond to a Tx Hang
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3354
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3355
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3356
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3357
static void e1000_tx_timeout(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3358
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3359
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3360
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3361
	/* Do the reset outside of interrupt context */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3362
	adapter->tx_timeout_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3363
	schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3364
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3365
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3366
static void e1000_reset_task(struct work_struct *work)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3367
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3368
	struct e1000_adapter *adapter =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3369
		container_of(work, struct e1000_adapter, reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3370
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3371
	e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3372
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3373
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3374
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3375
 * e1000_get_stats - Get System Network Statistics
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3376
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3377
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3378
 * Returns the address of the device statistics structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3379
 * The statistics are actually updated from the timer callback.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3380
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3381
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3382
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3383
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3384
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3385
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3386
	/* only return the current stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3387
	return &adapter->net_stats;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3388
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3389
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3390
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3391
 * e1000_change_mtu - Change the Maximum Transfer Unit
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3392
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3393
 * @new_mtu: new value for maximum frame size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3394
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3395
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3396
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3397
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3398
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3399
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3400
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3401
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3402
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3403
	u16 eeprom_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3404
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3405
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3406
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3407
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3408
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3409
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3410
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3411
	/* Adapter-specific max frame size limits. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3412
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3413
	case e1000_undefined ... e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3414
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3415
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3416
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3417
			return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3418
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3419
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3420
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3421
		/* Jumbo Frames not supported if:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3422
		 * - this is not an 82573L device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3423
		 * - ASPM is enabled in any way (0x1A bits 3:2) */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3424
		e1000_read_eeprom(hw, EEPROM_INIT_3GIO_3, 1,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3425
		                  &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3426
		if ((hw->device_id != E1000_DEV_ID_82573L) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3427
		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3428
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3429
				DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3430
			            	"Jumbo Frames not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3431
				return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3432
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3433
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3434
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3435
		/* ERT will be enabled later to enable wire speed receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3436
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3437
		/* fall through to get support */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3438
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3439
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3440
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3441
#define MAX_STD_JUMBO_FRAME_SIZE 9234
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3442
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3443
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3444
			return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3445
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3446
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3447
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3448
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3449
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3450
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3451
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3452
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3453
	 * means we reserve 2 more, this pushes us to allocate from the next
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3454
	 * larger slab size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3455
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3456
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3457
	if (max_frame <= E1000_RXBUFFER_256)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3458
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3459
	else if (max_frame <= E1000_RXBUFFER_512)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3460
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3461
	else if (max_frame <= E1000_RXBUFFER_1024)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3462
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3463
	else if (max_frame <= E1000_RXBUFFER_2048)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3464
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3465
	else if (max_frame <= E1000_RXBUFFER_4096)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3466
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3467
	else if (max_frame <= E1000_RXBUFFER_8192)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3468
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3469
	else if (max_frame <= E1000_RXBUFFER_16384)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3470
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3471
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3472
	/* adjust allocation if LPE protects us, and we aren't using SBP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3473
	if (!hw->tbi_compatibility_on &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3474
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3475
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3476
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3477
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3478
	netdev->mtu = new_mtu;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3479
	hw->max_frame_size = max_frame;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3480
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3481
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3482
		e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3483
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3484
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3485
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3486
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3487
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3488
 * e1000_update_stats - Update the board statistics counters
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3489
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3490
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3491
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3492
void e1000_update_stats(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3493
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3494
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3495
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3496
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3497
	u16 phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3498
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3499
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3500
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3501
	/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3502
	 * Prevent stats update while adapter is being reset, or if the pci
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3503
	 * connection is down.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3504
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3505
	if (adapter->link_speed == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3506
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3507
	if (pci_channel_offline(pdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3508
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3509
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3510
	spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3511
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3512
	/* these counters are modified from e1000_tbi_adjust_stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3513
	 * called from the interrupt context, so they must only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3514
	 * be written while holding adapter->stats_lock
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3515
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3516
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3517
	adapter->stats.crcerrs += er32(CRCERRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3518
	adapter->stats.gprc += er32(GPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3519
	adapter->stats.gorcl += er32(GORCL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3520
	adapter->stats.gorch += er32(GORCH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3521
	adapter->stats.bprc += er32(BPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3522
	adapter->stats.mprc += er32(MPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3523
	adapter->stats.roc += er32(ROC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3524
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3525
	if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3526
		adapter->stats.prc64 += er32(PRC64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3527
		adapter->stats.prc127 += er32(PRC127);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3528
		adapter->stats.prc255 += er32(PRC255);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3529
		adapter->stats.prc511 += er32(PRC511);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3530
		adapter->stats.prc1023 += er32(PRC1023);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3531
		adapter->stats.prc1522 += er32(PRC1522);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3532
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3533
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3534
	adapter->stats.symerrs += er32(SYMERRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3535
	adapter->stats.mpc += er32(MPC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3536
	adapter->stats.scc += er32(SCC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3537
	adapter->stats.ecol += er32(ECOL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3538
	adapter->stats.mcc += er32(MCC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3539
	adapter->stats.latecol += er32(LATECOL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3540
	adapter->stats.dc += er32(DC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3541
	adapter->stats.sec += er32(SEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3542
	adapter->stats.rlec += er32(RLEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3543
	adapter->stats.xonrxc += er32(XONRXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3544
	adapter->stats.xontxc += er32(XONTXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3545
	adapter->stats.xoffrxc += er32(XOFFRXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3546
	adapter->stats.xofftxc += er32(XOFFTXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3547
	adapter->stats.fcruc += er32(FCRUC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3548
	adapter->stats.gptc += er32(GPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3549
	adapter->stats.gotcl += er32(GOTCL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3550
	adapter->stats.gotch += er32(GOTCH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3551
	adapter->stats.rnbc += er32(RNBC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3552
	adapter->stats.ruc += er32(RUC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3553
	adapter->stats.rfc += er32(RFC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3554
	adapter->stats.rjc += er32(RJC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3555
	adapter->stats.torl += er32(TORL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3556
	adapter->stats.torh += er32(TORH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3557
	adapter->stats.totl += er32(TOTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3558
	adapter->stats.toth += er32(TOTH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3559
	adapter->stats.tpr += er32(TPR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3560
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3561
	if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3562
		adapter->stats.ptc64 += er32(PTC64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3563
		adapter->stats.ptc127 += er32(PTC127);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3564
		adapter->stats.ptc255 += er32(PTC255);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3565
		adapter->stats.ptc511 += er32(PTC511);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3566
		adapter->stats.ptc1023 += er32(PTC1023);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3567
		adapter->stats.ptc1522 += er32(PTC1522);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3568
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3569
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3570
	adapter->stats.mptc += er32(MPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3571
	adapter->stats.bptc += er32(BPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3572
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3573
	/* used for adaptive IFS */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3574
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3575
	hw->tx_packet_delta = er32(TPT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3576
	adapter->stats.tpt += hw->tx_packet_delta;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3577
	hw->collision_delta = er32(COLC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3578
	adapter->stats.colc += hw->collision_delta;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3579
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3580
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3581
		adapter->stats.algnerrc += er32(ALGNERRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3582
		adapter->stats.rxerrc += er32(RXERRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3583
		adapter->stats.tncrs += er32(TNCRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3584
		adapter->stats.cexterr += er32(CEXTERR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3585
		adapter->stats.tsctc += er32(TSCTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3586
		adapter->stats.tsctfc += er32(TSCTFC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3587
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3588
	if (hw->mac_type > e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3589
		adapter->stats.iac += er32(IAC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3590
		adapter->stats.icrxoc += er32(ICRXOC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3591
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3592
		if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3593
			adapter->stats.icrxptc += er32(ICRXPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3594
			adapter->stats.icrxatc += er32(ICRXATC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3595
			adapter->stats.ictxptc += er32(ICTXPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3596
			adapter->stats.ictxatc += er32(ICTXATC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3597
			adapter->stats.ictxqec += er32(ICTXQEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3598
			adapter->stats.ictxqmtc += er32(ICTXQMTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3599
			adapter->stats.icrxdmtc += er32(ICRXDMTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3600
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3601
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3602
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3603
	/* Fill out the OS statistics structure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3604
	adapter->net_stats.multicast = adapter->stats.mprc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3605
	adapter->net_stats.collisions = adapter->stats.colc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3606
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3607
	/* Rx Errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3608
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3609
	/* RLEC on some newer hardware can be incorrect so build
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3610
	* our own version based on RUC and ROC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3611
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3612
		adapter->stats.crcerrs + adapter->stats.algnerrc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3613
		adapter->stats.ruc + adapter->stats.roc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3614
		adapter->stats.cexterr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3615
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3616
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3617
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3618
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3619
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3620
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3621
	/* Tx Errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3622
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3623
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3624
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3625
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3626
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3627
	if (hw->bad_tx_carr_stats_fd &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3628
	    adapter->link_duplex == FULL_DUPLEX) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3629
		adapter->net_stats.tx_carrier_errors = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3630
		adapter->stats.tncrs = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3631
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3632
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3633
	/* Tx Dropped needs to be maintained elsewhere */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3634
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3635
	/* Phy Stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3636
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3637
		if ((adapter->link_speed == SPEED_1000) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3638
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3639
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3640
			adapter->phy_stats.idle_errors += phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3641
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3642
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3643
		if ((hw->mac_type <= e1000_82546) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3644
		   (hw->phy_type == e1000_phy_m88) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3645
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3646
			adapter->phy_stats.receive_errors += phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3647
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3648
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3649
	/* Management Stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3650
	if (hw->has_smbus) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3651
		adapter->stats.mgptc += er32(MGTPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3652
		adapter->stats.mgprc += er32(MGTPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3653
		adapter->stats.mgpdc += er32(MGTPDC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3654
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3655
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3656
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3657
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3658
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3659
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3660
 * e1000_intr_msi - Interrupt Handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3661
 * @irq: interrupt number
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3662
 * @data: pointer to a network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3663
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3664
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3665
static irqreturn_t e1000_intr_msi(int irq, void *data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3666
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3667
	struct net_device *netdev = data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3668
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3669
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3670
	u32 icr = er32(ICR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3671
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3672
	/* in NAPI mode read ICR disables interrupts using IAM */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3673
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3674
	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3675
		hw->get_link_status = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3676
		/* 80003ES2LAN workaround-- For packet buffer work-around on
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3677
		 * link down event; disable receives here in the ISR and reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3678
		 * adapter in watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3679
		if (netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3680
		    (hw->mac_type == e1000_80003es2lan)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3681
			/* disable receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3682
			u32 rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3683
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3684
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3685
		/* guard against interrupt when we're going down */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3686
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3687
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3688
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3689
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3690
	if (likely(netif_rx_schedule_prep(&adapter->napi))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3691
		adapter->total_tx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3692
		adapter->total_tx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3693
		adapter->total_rx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3694
		adapter->total_rx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3695
		__netif_rx_schedule(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3696
	} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3697
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3698
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3699
	return IRQ_HANDLED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3700
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3701
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3702
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3703
 * e1000_intr - Interrupt Handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3704
 * @irq: interrupt number
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3705
 * @data: pointer to a network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3706
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3707
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3708
static irqreturn_t e1000_intr(int irq, void *data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3709
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3710
	struct net_device *netdev = data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3711
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3712
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3713
	u32 rctl, icr = er32(ICR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3714
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3715
	if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3716
		return IRQ_NONE;  /* Not our interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3717
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3718
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3719
	 * not set, then the adapter didn't send an interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3720
	if (unlikely(hw->mac_type >= e1000_82571 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3721
	             !(icr & E1000_ICR_INT_ASSERTED)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3722
		return IRQ_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3723
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3724
	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3725
	 * need for the IMC write */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3726
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3727
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3728
		hw->get_link_status = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3729
		/* 80003ES2LAN workaround--
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3730
		 * For packet buffer work-around on link down event;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3731
		 * disable receives here in the ISR and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3732
		 * reset adapter in watchdog
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3733
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3734
		if (netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3735
		    (hw->mac_type == e1000_80003es2lan)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3736
			/* disable receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3737
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3738
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3739
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3740
		/* guard against interrupt when we're going down */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3741
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3742
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3743
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3744
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3745
	if (unlikely(hw->mac_type < e1000_82571)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3746
		/* disable interrupts, without the synchronize_irq bit */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3747
		ew32(IMC, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3748
		E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3749
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3750
	if (likely(netif_rx_schedule_prep(&adapter->napi))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3751
		adapter->total_tx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3752
		adapter->total_tx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3753
		adapter->total_rx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3754
		adapter->total_rx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3755
		__netif_rx_schedule(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3756
	} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3757
		/* this really should not happen! if it does it is basically a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3758
		 * bug, but not a hard error, so enable ints and continue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3759
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3760
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3761
	return IRQ_HANDLED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3762
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3763
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3764
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3765
 * e1000_clean - NAPI Rx polling callback
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3766
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3767
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3768
static int e1000_clean(struct napi_struct *napi, int budget)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3769
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3770
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3771
	struct net_device *poll_dev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3772
	int tx_cleaned = 0, work_done = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3773
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3774
	adapter = netdev_priv(poll_dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3775
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3776
	/* e1000_clean is called per-cpu.  This lock protects
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3777
	 * tx_ring[0] from being cleaned by multiple cpus
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3778
	 * simultaneously.  A failure obtaining the lock means
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3779
	 * tx_ring[0] is currently being cleaned anyway. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3780
	if (spin_trylock(&adapter->tx_queue_lock)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3781
		tx_cleaned = e1000_clean_tx_irq(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3782
						&adapter->tx_ring[0]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3783
		spin_unlock(&adapter->tx_queue_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3784
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3785
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3786
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3787
	                  &work_done, budget);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3788
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3789
	if (tx_cleaned)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3790
		work_done = budget;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3791
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3792
	/* If budget not fully consumed, exit the polling mode */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3793
	if (work_done < budget) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3794
		if (likely(adapter->itr_setting & 3))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3795
			e1000_set_itr(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3796
		netif_rx_complete(napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3797
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3798
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3799
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3800
	return work_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3801
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3802
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3803
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3804
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3805
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3806
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3807
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3808
			       struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3809
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3810
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3811
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3812
	struct e1000_tx_desc *tx_desc, *eop_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3813
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3814
	unsigned int i, eop;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3815
	unsigned int count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3816
	bool cleaned = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3817
	unsigned int total_tx_bytes=0, total_tx_packets=0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3818
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3819
	i = tx_ring->next_to_clean;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3820
	eop = tx_ring->buffer_info[i].next_to_watch;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3821
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3822
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3823
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3824
		for (cleaned = false; !cleaned; ) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3825
			tx_desc = E1000_TX_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3826
			buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3827
			cleaned = (i == eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3828
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3829
			if (cleaned) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3830
				struct sk_buff *skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3831
				unsigned int segs, bytecount;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3832
				segs = skb_shinfo(skb)->gso_segs ?: 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3833
				/* multiply data chunks by size of headers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3834
				bytecount = ((segs - 1) * skb_headlen(skb)) +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3835
				            skb->len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3836
				total_tx_packets += segs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3837
				total_tx_bytes += bytecount;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3838
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3839
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3840
			tx_desc->upper.data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3841
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3842
			if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3843
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3844
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3845
		eop = tx_ring->buffer_info[i].next_to_watch;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3846
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3847
#define E1000_TX_WEIGHT 64
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3848
		/* weight of a sort for tx, to avoid endless transmit cleanup */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3849
		if (count++ == E1000_TX_WEIGHT)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3850
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3851
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3852
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3853
	tx_ring->next_to_clean = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3854
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3855
#define TX_WAKE_THRESHOLD 32
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3856
	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3857
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3858
		/* Make sure that anybody stopping the queue after this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3859
		 * sees the new next_to_clean.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3860
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3861
		smp_mb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3862
		if (netif_queue_stopped(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3863
			netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3864
			++adapter->restart_queue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3865
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3866
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3867
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3868
	if (adapter->detect_tx_hung) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3869
		/* Detect a transmit hang in hardware, this serializes the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3870
		 * check with the clearing of time_stamp and movement of i */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3871
		adapter->detect_tx_hung = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3872
		if (tx_ring->buffer_info[eop].dma &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3873
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3874
		               (adapter->tx_timeout_factor * HZ))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3875
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3876
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3877
			/* detected Tx unit hang */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3878
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3879
					"  Tx Queue             <%lu>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3880
					"  TDH                  <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3881
					"  TDT                  <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3882
					"  next_to_use          <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3883
					"  next_to_clean        <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3884
					"buffer_info[next_to_clean]\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3885
					"  time_stamp           <%lx>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3886
					"  next_to_watch        <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3887
					"  jiffies              <%lx>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3888
					"  next_to_watch.status <%x>\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3889
				(unsigned long)((tx_ring - adapter->tx_ring) /
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3890
					sizeof(struct e1000_tx_ring)),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3891
				readl(hw->hw_addr + tx_ring->tdh),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3892
				readl(hw->hw_addr + tx_ring->tdt),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3893
				tx_ring->next_to_use,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3894
				tx_ring->next_to_clean,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3895
				tx_ring->buffer_info[eop].time_stamp,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3896
				eop,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3897
				jiffies,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3898
				eop_desc->upper.fields.status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3899
			netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3900
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3901
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3902
	adapter->total_tx_bytes += total_tx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3903
	adapter->total_tx_packets += total_tx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3904
	adapter->net_stats.tx_bytes += total_tx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3905
	adapter->net_stats.tx_packets += total_tx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3906
	return cleaned;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3907
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3908
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3909
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3910
 * e1000_rx_checksum - Receive Checksum Offload for 82543
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3911
 * @adapter:     board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3912
 * @status_err:  receive descriptor status and error fields
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3913
 * @csum:        receive descriptor csum field
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3914
 * @sk_buff:     socket buffer with received data
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3915
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3916
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3917
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3918
			      u32 csum, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3919
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3920
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3921
	u16 status = (u16)status_err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3922
	u8 errors = (u8)(status_err >> 24);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3923
	skb->ip_summed = CHECKSUM_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3924
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3925
	/* 82543 or newer only */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3926
	if (unlikely(hw->mac_type < e1000_82543)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3927
	/* Ignore Checksum bit is set */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3928
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3929
	/* TCP/UDP checksum error bit is set */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3930
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3931
		/* let the stack verify checksum errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3932
		adapter->hw_csum_err++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3933
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3934
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3935
	/* TCP/UDP Checksum has not been calculated */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3936
	if (hw->mac_type <= e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3937
		if (!(status & E1000_RXD_STAT_TCPCS))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3938
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3939
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3940
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3941
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3942
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3943
	/* It must be a TCP or UDP packet with a valid checksum */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3944
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3945
		/* TCP checksum is good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3946
		skb->ip_summed = CHECKSUM_UNNECESSARY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3947
	} else if (hw->mac_type > e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3948
		/* IP fragment with UDP payload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3949
		/* Hardware complements the payload checksum, so we undo it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3950
		 * and then put the value in host order for further stack use.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3951
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3952
		__sum16 sum = (__force __sum16)htons(csum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3953
		skb->csum = csum_unfold(~sum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3954
		skb->ip_summed = CHECKSUM_COMPLETE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3955
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3956
	adapter->hw_csum_good++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3957
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3958
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3959
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3960
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3961
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3962
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3963
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3964
			       struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3965
			       int *work_done, int work_to_do)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3966
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3967
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3968
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3969
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3970
	struct e1000_rx_desc *rx_desc, *next_rxd;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3971
	struct e1000_buffer *buffer_info, *next_buffer;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3972
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3973
	u32 length;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3974
	u8 last_byte;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3975
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3976
	int cleaned_count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3977
	bool cleaned = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3978
	unsigned int total_rx_bytes=0, total_rx_packets=0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3979
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3980
	i = rx_ring->next_to_clean;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3981
	rx_desc = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3982
	buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3983
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3984
	while (rx_desc->status & E1000_RXD_STAT_DD) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3985
		struct sk_buff *skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3986
		u8 status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3987
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3988
		if (*work_done >= work_to_do)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3989
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3990
		(*work_done)++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3991
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3992
		status = rx_desc->status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3993
		skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3994
		buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3995
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3996
		prefetch(skb->data - NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3997
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3998
		if (++i == rx_ring->count) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3999
		next_rxd = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4000
		prefetch(next_rxd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4001
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4002
		next_buffer = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4003
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4004
		cleaned = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4005
		cleaned_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4006
		pci_unmap_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4007
		                 buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4008
		                 buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4009
		                 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4010
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4011
		length = le16_to_cpu(rx_desc->length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4012
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4013
		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4014
			/* All receives must fit into a single buffer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4015
			E1000_DBG("%s: Receive packet consumed multiple"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4016
				  " buffers\n", netdev->name);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4017
			/* recycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4018
			buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4019
			goto next_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4020
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4021
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4022
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4023
			last_byte = *(skb->data + length - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4024
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4025
				       last_byte)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4026
				spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4027
				e1000_tbi_adjust_stats(hw, &adapter->stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4028
				                       length, skb->data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4029
				spin_unlock_irqrestore(&adapter->stats_lock,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4030
				                       flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4031
				length--;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4032
			} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4033
				/* recycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4034
				buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4035
				goto next_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4036
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4037
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4038
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4039
		/* adjust length to remove Ethernet CRC, this must be
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4040
		 * done after the TBI_ACCEPT workaround above */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4041
		length -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4042
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4043
		/* probably a little skewed due to removing CRC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4044
		total_rx_bytes += length;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4045
		total_rx_packets++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4046
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4047
		/* code added for copybreak, this should improve
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4048
		 * performance for small packets with large amounts
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4049
		 * of reassembly being done in the stack */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4050
		if (length < copybreak) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4051
			struct sk_buff *new_skb =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4052
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4053
			if (new_skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4054
				skb_reserve(new_skb, NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4055
				skb_copy_to_linear_data_offset(new_skb,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4056
							       -NET_IP_ALIGN,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4057
							       (skb->data -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4058
							        NET_IP_ALIGN),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4059
							       (length +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4060
							        NET_IP_ALIGN));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4061
				/* save the skb in buffer_info as good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4062
				buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4063
				skb = new_skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4064
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4065
			/* else just continue with the old one */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4066
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4067
		/* end copybreak code */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4068
		skb_put(skb, length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4069
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4070
		/* Receive Checksum Offload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4071
		e1000_rx_checksum(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4072
				  (u32)(status) |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4073
				  ((u32)(rx_desc->errors) << 24),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4074
				  le16_to_cpu(rx_desc->csum), skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4075
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4076
		skb->protocol = eth_type_trans(skb, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4077
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4078
		if (unlikely(adapter->vlgrp &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4079
			    (status & E1000_RXD_STAT_VP))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4080
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4081
						 le16_to_cpu(rx_desc->special));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4082
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4083
			netif_receive_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4084
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4085
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4086
next_desc:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4087
		rx_desc->status = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4088
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4089
		/* return some buffers to hardware, one at a time is too slow */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4090
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4091
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4092
			cleaned_count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4093
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4094
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4095
		/* use prefetched values */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4096
		rx_desc = next_rxd;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4097
		buffer_info = next_buffer;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4098
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4099
	rx_ring->next_to_clean = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4100
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4101
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4102
	if (cleaned_count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4103
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4104
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4105
	adapter->total_rx_packets += total_rx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4106
	adapter->total_rx_bytes += total_rx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4107
	adapter->net_stats.rx_bytes += total_rx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4108
	adapter->net_stats.rx_packets += total_rx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4109
	return cleaned;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4110
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4111
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4112
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4113
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4114
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4115
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4116
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4117
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4118
				   struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4119
				   int cleaned_count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4120
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4121
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4122
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4123
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4124
	struct e1000_rx_desc *rx_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4125
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4126
	struct sk_buff *skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4127
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4128
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4129
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4130
	i = rx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4131
	buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4132
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4133
	while (cleaned_count--) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4134
		skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4135
		if (skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4136
			skb_trim(skb, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4137
			goto map_skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4138
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4139
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4140
		skb = netdev_alloc_skb(netdev, bufsz);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4141
		if (unlikely(!skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4142
			/* Better luck next round */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4143
			adapter->alloc_rx_buff_failed++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4144
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4145
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4146
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4147
		/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4148
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4149
			struct sk_buff *oldskb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4150
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4151
					     "at %p\n", bufsz, skb->data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4152
			/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4153
			skb = netdev_alloc_skb(netdev, bufsz);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4154
			/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4155
			if (!skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4156
				dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4157
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4158
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4159
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4160
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4161
				/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4162
				dev_kfree_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4163
				dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4164
				break; /* while !buffer_info->skb */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4165
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4166
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4167
			/* Use new allocation */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4168
			dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4169
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4170
		/* Make buffer alignment 2 beyond a 16 byte boundary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4171
		 * this will result in a 16 byte aligned IP header after
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4172
		 * the 14 byte MAC header is removed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4173
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4174
		skb_reserve(skb, NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4175
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4176
		buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4177
		buffer_info->length = adapter->rx_buffer_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4178
map_skb:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4179
		buffer_info->dma = pci_map_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4180
						  skb->data,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4181
						  adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4182
						  PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4183
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4184
		/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4185
		if (!e1000_check_64k_bound(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4186
					(void *)(unsigned long)buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4187
					adapter->rx_buffer_len)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4188
			DPRINTK(RX_ERR, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4189
				"dma align check failed: %u bytes at %p\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4190
				adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4191
				(void *)(unsigned long)buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4192
			dev_kfree_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4193
			buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4194
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4195
			pci_unmap_single(pdev, buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4196
					 adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4197
					 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4198
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4199
			break; /* while !buffer_info->skb */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4200
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4201
		rx_desc = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4202
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4203
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4204
		if (unlikely(++i == rx_ring->count))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4205
			i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4206
		buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4207
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4208
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4209
	if (likely(rx_ring->next_to_use != i)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4210
		rx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4211
		if (unlikely(i-- == 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4212
			i = (rx_ring->count - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4213
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4214
		/* Force memory writes to complete before letting h/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4215
		 * know there are new descriptors to fetch.  (Only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4216
		 * applicable for weak-ordered memory model archs,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4217
		 * such as IA-64). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4218
		wmb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4219
		writel(i, hw->hw_addr + rx_ring->rdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4220
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4221
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4222
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4223
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4224
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4225
 * @adapter:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4226
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4227
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4228
static void e1000_smartspeed(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4229
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4230
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4231
	u16 phy_status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4232
	u16 phy_ctrl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4233
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4234
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4235
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4236
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4237
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4238
	if (adapter->smartspeed == 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4239
		/* If Master/Slave config fault is asserted twice,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4240
		 * we assume back-to-back */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4241
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4242
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4243
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4244
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4245
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4246
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4247
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4248
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4249
					    phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4250
			adapter->smartspeed++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4251
			if (!e1000_phy_setup_autoneg(hw) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4252
			   !e1000_read_phy_reg(hw, PHY_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4253
				   	       &phy_ctrl)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4254
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4255
					     MII_CR_RESTART_AUTO_NEG);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4256
				e1000_write_phy_reg(hw, PHY_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4257
						    phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4258
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4259
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4260
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4261
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4262
		/* If still no link, perhaps using 2/3 pair cable */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4263
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4264
		phy_ctrl |= CR_1000T_MS_ENABLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4265
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4266
		if (!e1000_phy_setup_autoneg(hw) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4267
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4268
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4269
				     MII_CR_RESTART_AUTO_NEG);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4270
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4271
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4272
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4273
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4274
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4275
		adapter->smartspeed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4276
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4277
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4278
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4279
 * e1000_ioctl -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4280
 * @netdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4281
 * @ifreq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4282
 * @cmd:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4283
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4284
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4285
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4286
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4287
	switch (cmd) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4288
	case SIOCGMIIPHY:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4289
	case SIOCGMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4290
	case SIOCSMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4291
		return e1000_mii_ioctl(netdev, ifr, cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4292
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4293
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4294
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4295
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4296
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4297
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4298
 * e1000_mii_ioctl -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4299
 * @netdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4300
 * @ifreq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4301
 * @cmd:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4302
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4303
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4304
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4305
			   int cmd)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4306
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4307
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4308
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4309
	struct mii_ioctl_data *data = if_mii(ifr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4310
	int retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4311
	u16 mii_reg;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4312
	u16 spddplx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4313
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4314
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4315
	if (hw->media_type != e1000_media_type_copper)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4316
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4317
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4318
	switch (cmd) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4319
	case SIOCGMIIPHY:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4320
		data->phy_id = hw->phy_addr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4321
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4322
	case SIOCGMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4323
		if (!capable(CAP_NET_ADMIN))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4324
			return -EPERM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4325
		spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4326
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4327
				   &data->val_out)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4328
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4329
			return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4330
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4331
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4332
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4333
	case SIOCSMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4334
		if (!capable(CAP_NET_ADMIN))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4335
			return -EPERM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4336
		if (data->reg_num & ~(0x1F))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4337
			return -EFAULT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4338
		mii_reg = data->val_in;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4339
		spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4340
		if (e1000_write_phy_reg(hw, data->reg_num,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4341
					mii_reg)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4342
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4343
			return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4344
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4345
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4346
		if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4347
			switch (data->reg_num) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4348
			case PHY_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4349
				if (mii_reg & MII_CR_POWER_DOWN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4350
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4351
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4352
					hw->autoneg = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4353
					hw->autoneg_advertised = 0x2F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4354
				} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4355
					if (mii_reg & 0x40)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4356
						spddplx = SPEED_1000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4357
					else if (mii_reg & 0x2000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4358
						spddplx = SPEED_100;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4359
					else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4360
						spddplx = SPEED_10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4361
					spddplx += (mii_reg & 0x100)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4362
						   ? DUPLEX_FULL :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4363
						   DUPLEX_HALF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4364
					retval = e1000_set_spd_dplx(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4365
								    spddplx);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4366
					if (retval)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4367
						return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4368
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4369
				if (netif_running(adapter->netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4370
					e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4371
				else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4372
					e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4373
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4374
			case M88E1000_PHY_SPEC_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4375
			case M88E1000_EXT_PHY_SPEC_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4376
				if (e1000_phy_reset(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4377
					return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4378
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4379
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4380
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4381
			switch (data->reg_num) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4382
			case PHY_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4383
				if (mii_reg & MII_CR_POWER_DOWN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4384
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4385
				if (netif_running(adapter->netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4386
					e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4387
				else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4388
					e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4389
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4390
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4391
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4392
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4393
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4394
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4395
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4396
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4397
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4398
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4399
void e1000_pci_set_mwi(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4400
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4401
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4402
	int ret_val = pci_set_mwi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4403
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4404
	if (ret_val)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4405
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4406
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4407
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4408
void e1000_pci_clear_mwi(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4409
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4410
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4411
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4412
	pci_clear_mwi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4413
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4414
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4415
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4416
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4417
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4418
	return pcix_get_mmrbc(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4419
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4420
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4421
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4422
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4423
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4424
	pcix_set_mmrbc(adapter->pdev, mmrbc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4425
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4426
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4427
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4428
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4429
    struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4430
    u16 cap_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4431
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4432
    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4433
    if (!cap_offset)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4434
        return -E1000_ERR_CONFIG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4435
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4436
    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4437
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4438
    return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4439
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4440
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4441
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4442
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4443
	outl(value, port);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4444
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4445
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4446
static void e1000_vlan_rx_register(struct net_device *netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4447
				   struct vlan_group *grp)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4448
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4449
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4450
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4451
	u32 ctrl, rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4452
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4453
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4454
		e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4455
	adapter->vlgrp = grp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4456
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4457
	if (grp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4458
		/* enable VLAN tag insert/strip */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4459
		ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4460
		ctrl |= E1000_CTRL_VME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4461
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4462
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4463
		if (adapter->hw.mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4464
			/* enable VLAN receive filtering */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4465
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4466
			rctl &= ~E1000_RCTL_CFIEN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4467
			ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4468
			e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4469
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4470
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4471
		/* disable VLAN tag insert/strip */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4472
		ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4473
		ctrl &= ~E1000_CTRL_VME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4474
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4475
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4476
		if (adapter->hw.mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4477
			if (adapter->mng_vlan_id !=
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4478
			    (u16)E1000_MNG_VLAN_NONE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4479
				e1000_vlan_rx_kill_vid(netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4480
				                       adapter->mng_vlan_id);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4481
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4482
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4483
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4484
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4485
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4486
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4487
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4488
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4489
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4490
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4491
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4492
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4493
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4494
	u32 vfta, index;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4495
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4496
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4497
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4498
	    (vid == adapter->mng_vlan_id))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4499
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4500
	/* add VID to filter table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4501
	index = (vid >> 5) & 0x7F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4502
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4503
	vfta |= (1 << (vid & 0x1F));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4504
	e1000_write_vfta(hw, index, vfta);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4505
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4506
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4507
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4508
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4509
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4510
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4511
	u32 vfta, index;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4512
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4513
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4514
		e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4515
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4516
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4517
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4518
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4519
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4520
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4521
	    (vid == adapter->mng_vlan_id)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4522
		/* release control to f/w */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4523
		e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4524
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4525
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4526
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4527
	/* remove VID from filter table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4528
	index = (vid >> 5) & 0x7F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4529
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4530
	vfta &= ~(1 << (vid & 0x1F));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4531
	e1000_write_vfta(hw, index, vfta);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4532
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4533
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4534
static void e1000_restore_vlan(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4535
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4536
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4537
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4538
	if (adapter->vlgrp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4539
		u16 vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4540
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4541
			if (!vlan_group_get_device(adapter->vlgrp, vid))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4542
				continue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4543
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4544
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4545
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4546
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4547
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4548
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4549
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4550
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4551
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4552
	hw->autoneg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4553
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4554
	/* Fiber NICs only allow 1000 gbps Full duplex */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4555
	if ((hw->media_type == e1000_media_type_fiber) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4556
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4557
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4558
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4559
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4560
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4561
	switch (spddplx) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4562
	case SPEED_10 + DUPLEX_HALF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4563
		hw->forced_speed_duplex = e1000_10_half;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4564
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4565
	case SPEED_10 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4566
		hw->forced_speed_duplex = e1000_10_full;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4567
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4568
	case SPEED_100 + DUPLEX_HALF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4569
		hw->forced_speed_duplex = e1000_100_half;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4570
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4571
	case SPEED_100 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4572
		hw->forced_speed_duplex = e1000_100_full;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4573
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4574
	case SPEED_1000 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4575
		hw->autoneg = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4576
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4577
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4578
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4579
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4580
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4581
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4582
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4583
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4584
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4585
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4586
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4587
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4588
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4589
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4590
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4591
	u32 ctrl, ctrl_ext, rctl, status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4592
	u32 wufc = adapter->wol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4593
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4594
	int retval = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4595
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4596
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4597
	netif_device_detach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4598
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4599
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4600
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4601
		e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4602
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4603
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4604
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4605
	retval = pci_save_state(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4606
	if (retval)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4607
		return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4608
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4609
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4610
	status = er32(STATUS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4611
	if (status & E1000_STATUS_LU)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4612
		wufc &= ~E1000_WUFC_LNKC;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4613
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4614
	if (wufc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4615
		e1000_setup_rctl(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4616
		e1000_set_rx_mode(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4617
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4618
		/* turn on all-multi mode if wake on multicast is enabled */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4619
		if (wufc & E1000_WUFC_MC) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4620
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4621
			rctl |= E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4622
			ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4623
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4624
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4625
		if (hw->mac_type >= e1000_82540) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4626
			ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4627
			/* advertise wake from D3Cold */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4628
			#define E1000_CTRL_ADVD3WUC 0x00100000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4629
			/* phy power management enable */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4630
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4631
			ctrl |= E1000_CTRL_ADVD3WUC |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4632
				E1000_CTRL_EN_PHY_PWR_MGMT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4633
			ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4634
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4635
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4636
		if (hw->media_type == e1000_media_type_fiber ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4637
		   hw->media_type == e1000_media_type_internal_serdes) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4638
			/* keep the laser running in D3 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4639
			ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4640
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4641
			ew32(CTRL_EXT, ctrl_ext);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4642
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4643
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4644
		/* Allow time for pending master requests to run */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4645
		e1000_disable_pciex_master(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4646
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4647
		ew32(WUC, E1000_WUC_PME_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4648
		ew32(WUFC, wufc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4649
		pci_enable_wake(pdev, PCI_D3hot, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4650
		pci_enable_wake(pdev, PCI_D3cold, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4651
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4652
		ew32(WUC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4653
		ew32(WUFC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4654
		pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4655
		pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4656
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4657
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4658
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4659
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4660
	/* make sure adapter isn't asleep if manageability is enabled */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4661
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4662
		pci_enable_wake(pdev, PCI_D3hot, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4663
		pci_enable_wake(pdev, PCI_D3cold, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4664
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4665
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4666
	if (hw->phy_type == e1000_phy_igp_3)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4667
		e1000_phy_powerdown_workaround(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4668
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4669
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4670
		e1000_free_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4671
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4672
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4673
	 * would have already happened in close and is redundant. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4674
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4675
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4676
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4677
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4678
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4679
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4680
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4681
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4682
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4683
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4684
static int e1000_resume(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4685
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4686
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4687
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4688
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4689
	u32 err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4690
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4691
	pci_set_power_state(pdev, PCI_D0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4692
	pci_restore_state(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4693
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4694
	if (adapter->need_ioport)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4695
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4696
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4697
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4698
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4699
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4700
		return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4701
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4702
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4703
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4704
	pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4705
	pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4706
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4707
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4708
		err = e1000_request_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4709
		if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4710
			return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4711
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4712
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4713
	e1000_power_up_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4714
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4715
	ew32(WUS, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4716
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4717
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4718
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4719
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4720
		e1000_up(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4721
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4722
	netif_device_attach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4723
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4724
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4725
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4726
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4727
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4728
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4729
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4730
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4731
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4732
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4733
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4734
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4735
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4736
static void e1000_shutdown(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4737
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4738
	e1000_suspend(pdev, PMSG_SUSPEND);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4739
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4740
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4741
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4742
/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4743
 * Polling 'interrupt' - used by things like netconsole to send skbs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4744
 * without having to re-enable interrupts. It's not called while
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4745
 * the interrupt routine is executing.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4746
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4747
static void e1000_netpoll(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4748
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4749
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4750
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4751
	disable_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4752
	e1000_intr(adapter->pdev->irq, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4753
	enable_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4754
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4755
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4756
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4757
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4758
 * e1000_io_error_detected - called when PCI error is detected
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4759
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4760
 * @state: The current pci conneection state
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4761
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4762
 * This function is called after a PCI bus error affecting
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4763
 * this device has been detected.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4764
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4765
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4766
						pci_channel_state_t state)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4767
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4768
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4769
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4770
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4771
	netif_device_detach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4772
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4773
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4774
		e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4775
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4776
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4777
	/* Request a slot slot reset. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4778
	return PCI_ERS_RESULT_NEED_RESET;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4779
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4780
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4781
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4782
 * e1000_io_slot_reset - called after the pci bus has been reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4783
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4784
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4785
 * Restart the card from scratch, as if from a cold-boot. Implementation
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4786
 * resembles the first-half of the e1000_resume routine.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4787
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4788
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4789
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4790
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4791
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4792
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4793
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4794
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4795
	if (adapter->need_ioport)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4796
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4797
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4798
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4799
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4800
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4801
		return PCI_ERS_RESULT_DISCONNECT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4802
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4803
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4804
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4805
	pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4806
	pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4807
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4808
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4809
	ew32(WUS, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4810
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4811
	return PCI_ERS_RESULT_RECOVERED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4812
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4813
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4814
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4815
 * e1000_io_resume - called when traffic can start flowing again.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4816
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4817
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4818
 * This callback is called when the error recovery driver tells us that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4819
 * its OK to resume normal operation. Implementation resembles the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4820
 * second-half of the e1000_resume routine.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4821
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4822
static void e1000_io_resume(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4823
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4824
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4825
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4826
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4827
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4828
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4829
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4830
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4831
		if (e1000_up(adapter)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4832
			printk("e1000: can't bring device back up after reset\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4833
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4834
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4835
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4836
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4837
	netif_device_attach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4838
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4839
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4840
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4841
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4842
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4843
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4844
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4845
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4846
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4847
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4848
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4849
/* e1000_main.c */