devices/e1000/e1000_main-2.6.28-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 10:12:55 -0400
changeset 2625 e25af8bd3957
parent 2051 3a066ec73fb2
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.
2051
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include "e1000.h"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "e1000";
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k3-NAPI"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
static struct pci_device_id e1000_pci_tbl[] = {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{0,}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
};
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
int e1000_up(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
void e1000_down(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
void e1000_reinit_locked(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
void e1000_reset(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
                             struct e1000_tx_ring *txdr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
                             struct e1000_rx_ring *rxdr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
                             struct e1000_tx_ring *tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
                             struct e1000_rx_ring *rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
void e1000_update_stats(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
static int e1000_init_module(void);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_exit_module(void);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void __devexit e1000_remove(struct pci_dev *pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
static int e1000_alloc_queues(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
static int e1000_sw_init(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
static int e1000_open(struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_close(struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_configure_tx(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_rx(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_setup_rctl(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
                                struct e1000_tx_ring *tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
                                struct e1000_rx_ring *rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_set_rx_mode(struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_update_phy_info(unsigned long data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_watchdog(unsigned long data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_82547_tx_fifo_stall(unsigned long data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static int e1000_set_mac(struct net_device *netdev, void *p);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static irqreturn_t e1000_intr(int irq, void *data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static irqreturn_t e1000_intr_msi(int irq, void *data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
			       struct e1000_tx_ring *tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
static int e1000_clean(struct napi_struct *napi, int budget);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
			       struct e1000_rx_ring *rx_ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
			       int *work_done, int work_to_do);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
                                   struct e1000_rx_ring *rx_ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
				   int cleaned_count);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
			   int cmd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static void e1000_tx_timeout(struct net_device *dev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static void e1000_reset_task(struct work_struct *work);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_smartspeed(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
                                       struct sk_buff *skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static void e1000_restore_vlan(struct e1000_adapter *adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
#ifdef CONFIG_PM
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static int e1000_resume(struct pci_dev *pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_shutdown(struct pci_dev *pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_NET_POLL_CONTROLLER
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
/* for netdump / net console */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static void e1000_netpoll (struct net_device *netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
#define COPYBREAK_DEFAULT 256
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
module_param(copybreak, uint, 0644);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
MODULE_PARM_DESC(copybreak,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
	"Maximum size of packet that is copied to a new buffer on receive");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
                     pci_channel_state_t state);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static void e1000_io_resume(struct pci_dev *pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static struct pci_error_handlers e1000_err_handler = {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	.error_detected = e1000_io_error_detected,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
	.slot_reset = e1000_io_slot_reset,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	.resume = e1000_io_resume,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
};
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static struct pci_driver e1000_driver = {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	.name     = e1000_driver_name,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	.id_table = e1000_pci_tbl,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	.probe    = e1000_probe,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	.remove   = __devexit_p(e1000_remove),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
#ifdef CONFIG_PM
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	/* Power Managment Hooks */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	.suspend  = e1000_suspend,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	.resume   = e1000_resume,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	.shutdown = e1000_shutdown,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	.err_handler = &e1000_err_handler
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
};
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
MODULE_LICENSE("GPL");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
MODULE_VERSION(DRV_VERSION);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
module_param(debug, int, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
 * e1000_init_module - Driver Registration Routine
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
 * e1000_init_module is the first routine called when the driver is
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
 * loaded. All it does is register with the PCI subsystem.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
static int __init e1000_init_module(void)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	int ret;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	printk(KERN_INFO "%s - version %s\n",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	       e1000_driver_string, e1000_driver_version);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	printk(KERN_INFO "%s\n", e1000_copyright);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	ret = pci_register_driver(&e1000_driver);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	if (copybreak != COPYBREAK_DEFAULT) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
		if (copybreak == 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
			printk(KERN_INFO "e1000: copybreak disabled\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
			printk(KERN_INFO "e1000: copybreak enabled for "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
			       "packets <= %u bytes\n", copybreak);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	return ret;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
module_init(e1000_init_module);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
 * e1000_exit_module - Driver Exit Cleanup Routine
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 * e1000_exit_module is called just before the driver is removed
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 * from memory.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
static void __exit e1000_exit_module(void)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	pci_unregister_driver(&e1000_driver);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
module_exit(e1000_exit_module);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
static int e1000_request_irq(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	irq_handler_t handler = e1000_intr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	int irq_flags = IRQF_SHARED;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	int err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	if (hw->mac_type >= e1000_82571) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
		adapter->have_msi = !pci_enable_msi(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
		if (adapter->have_msi) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			handler = e1000_intr_msi;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
			irq_flags = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	                  netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		if (adapter->have_msi)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
			pci_disable_msi(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		        "Unable to allocate interrupt Error: %d\n", err);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
static void e1000_free_irq(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	free_irq(adapter->pdev->irq, netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	if (adapter->have_msi)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		pci_disable_msi(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
 * e1000_irq_disable - Mask off interrupt generation on the NIC
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
static void e1000_irq_disable(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	ew32(IMC, ~0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	synchronize_irq(adapter->pdev->irq);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
 * e1000_irq_enable - Enable default interrupt generation settings
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
static void e1000_irq_enable(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	ew32(IMS, IMS_ENABLE_MASK);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	u16 vid = hw->mng_cookie.vlan_id;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	u16 old_vid = adapter->mng_vlan_id;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	if (adapter->vlgrp) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
			if (hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
				e1000_vlan_rx_add_vid(netdev, vid);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
				adapter->mng_vlan_id = vid;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
			} else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
					(vid != old_vid) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
				e1000_vlan_rx_kill_vid(netdev, old_vid);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		} else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
			adapter->mng_vlan_id = vid;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
 * e1000_release_hw_control - release control of the h/w to f/w
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
 * @adapter: address of board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
 * For ASF and Pass Through versions of f/w this means that the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
 * driver is no longer loaded. For AMT version (only with 82573) i
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
 * of the f/w this means that the network i/f is closed.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
static void e1000_release_hw_control(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	u32 ctrl_ext;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
	u32 swsm;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	/* Let firmware taken over control of h/w */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		swsm = er32(SWSM);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
	case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		ctrl_ext = er32(CTRL_EXT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
 * e1000_get_hw_control - get control of the h/w from f/w
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
 * @adapter: address of board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
 * For ASF and Pass Through versions of f/w this means that
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
 * the driver is loaded. For AMT version (only with 82573)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
 * of the f/w this means that the network i/f is open.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
static void e1000_get_hw_control(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	u32 ctrl_ext;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	u32 swsm;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	/* Let firmware know the driver has taken over */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		swsm = er32(SWSM);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		ctrl_ext = er32(CTRL_EXT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
static void e1000_init_manageability(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	if (adapter->en_mng_pt) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
		u32 manc = er32(MANC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
		/* disable hardware interception of ARP */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
		manc &= ~(E1000_MANC_ARP_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		/* enable receiving management packets to the host */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		/* this will probably generate destination unreachable messages
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		 * from the host OS, but the packets will be handled on SMBUS */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		if (hw->has_manc2h) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			u32 manc2h = er32(MANC2H);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
			manc |= E1000_MANC_EN_MNG2HOST;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
#define E1000_MNG2HOST_PORT_623 (1 << 5)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
#define E1000_MNG2HOST_PORT_664 (1 << 6)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
			manc2h |= E1000_MNG2HOST_PORT_623;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
			manc2h |= E1000_MNG2HOST_PORT_664;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
			ew32(MANC2H, manc2h);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		ew32(MANC, manc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
static void e1000_release_manageability(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	if (adapter->en_mng_pt) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
		u32 manc = er32(MANC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
		/* re-enable hardware interception of ARP */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		manc |= E1000_MANC_ARP_EN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		if (hw->has_manc2h)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
			manc &= ~E1000_MANC_EN_MNG2HOST;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		/* don't explicitly have to mess with MANC2H since
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		 * MANC has an enable disable that gates MANC2H */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		ew32(MANC, manc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 * e1000_configure - configure the hardware for RX and TX
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
 * @adapter = private board structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
static void e1000_configure(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	e1000_set_rx_mode(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	e1000_restore_vlan(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	e1000_init_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	e1000_configure_tx(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	e1000_setup_rctl(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	e1000_configure_rx(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	/* call E1000_DESC_UNUSED which always leaves
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	 * at least 1 descriptor unused to make sure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	 * next_to_use != next_to_clean */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	for (i = 0; i < adapter->num_rx_queues; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		adapter->alloc_rx_buf(adapter, ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		                      E1000_DESC_UNUSED(ring));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	adapter->tx_queue_len = netdev->tx_queue_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
int e1000_up(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	/* hardware has been reset, we need to reload some things */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	e1000_configure(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	clear_bit(__E1000_DOWN, &adapter->flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	napi_enable(&adapter->napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	/* fire a link change interrupt to start the watchdog */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	ew32(ICS, E1000_ICS_LSC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 * e1000_power_up_phy - restore link in case the phy was powered down
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 * @adapter: address of board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
 * The phy may be powered down to save power and turn off link when the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
 * driver is unloaded and wake on lan is not enabled (among others)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
 * *** this routine MUST be followed by a call to e1000_reset ***
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
void e1000_power_up_phy(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	u16 mii_reg = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	/* Just clear the power down bit to wake the phy back up */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	if (hw->media_type == e1000_media_type_copper) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		/* according to the manual, the phy will retain its
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
		 * settings across a power-down/up cycle */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		mii_reg &= ~MII_CR_POWER_DOWN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
static void e1000_power_down_phy(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
	/* Power down the PHY so no link is implied when interface is down *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	 * The PHY cannot be powered down if any of the following is true *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	 * (a) WoL is enabled
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	 * (b) AMT is active
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	 * (c) SoL/IDER session is active */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	   hw->media_type == e1000_media_type_copper) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
		u16 mii_reg = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		case e1000_82540:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
		case e1000_82545:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		case e1000_82545_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		case e1000_82546:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
		case e1000_82546_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		case e1000_82541:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		case e1000_82541_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
		case e1000_82547:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		case e1000_82547_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
				goto out;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
		case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
			if (e1000_check_mng_mode(hw) ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			    e1000_check_phy_reset_block(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
				goto out;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
			goto out;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		mii_reg |= MII_CR_POWER_DOWN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		mdelay(1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
out:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
void e1000_down(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	/* signal that we're down so the interrupt handler does not
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	 * reschedule our watchdog timer */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	set_bit(__E1000_DOWN, &adapter->flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	napi_disable(&adapter->napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	e1000_irq_disable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	del_timer_sync(&adapter->tx_fifo_stall_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	del_timer_sync(&adapter->watchdog_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	del_timer_sync(&adapter->phy_info_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	netdev->tx_queue_len = adapter->tx_queue_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	adapter->link_speed = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	adapter->link_duplex = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	netif_carrier_off(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	e1000_clean_all_tx_rings(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	e1000_clean_all_rx_rings(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
void e1000_reinit_locked(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	WARN_ON(in_interrupt());
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		msleep(1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	e1000_down(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	e1000_up(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	clear_bit(__E1000_RESETTING, &adapter->flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
void e1000_reset(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	bool legacy_pba_adjust = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	/* Repartition Pba for greater than 9k mtu
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	 * To take effect CTRL.RST is required.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	case e1000_82542_rev2_0:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	case e1000_82542_rev2_1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	case e1000_82543:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	case e1000_82544:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	case e1000_82540:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	case e1000_82541:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	case e1000_82541_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		legacy_pba_adjust = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		pba = E1000_PBA_48K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	case e1000_82545:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	case e1000_82545_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	case e1000_82546:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	case e1000_82546_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		pba = E1000_PBA_48K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	case e1000_82547:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	case e1000_82547_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		legacy_pba_adjust = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		pba = E1000_PBA_30K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		pba = E1000_PBA_38K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		pba = E1000_PBA_20K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		pba = E1000_PBA_8K;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	case e1000_undefined:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	case e1000_num_macs:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	if (legacy_pba_adjust) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
			pba -= 8; /* allocate more FIFO for Tx */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		if (hw->mac_type == e1000_82547) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
			adapter->tx_fifo_head = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
			adapter->tx_fifo_size =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
			atomic_set(&adapter->tx_fifo_stall, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	} else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		/* adjust PBA for jumbo frames */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		ew32(PBA, pba);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		/* To maintain wire speed transmits, the Tx FIFO should be
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		 * large enough to accomodate two full transmit packets,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		 * the Rx FIFO should be large enough to accomodate at least
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		 * one full receive packet and is similarly rounded up and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		 * expressed in KB. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		pba = er32(PBA);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		/* upper 16 bits has Tx packet buffer allocation size in KB */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		tx_space = pba >> 16;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		/* lower 16 bits has Rx packet buffer allocation size in KB */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		pba &= 0xffff;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		/* don't include ethernet FCS because hardware appends/strips */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		               VLAN_TAG_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		min_tx_space = min_rx_space;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		min_tx_space *= 2;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		min_tx_space = ALIGN(min_tx_space, 1024);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		min_tx_space >>= 10;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
		min_rx_space = ALIGN(min_rx_space, 1024);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		min_rx_space >>= 10;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		/* If current Tx allocation is less than the min Tx FIFO size,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		 * and the min Tx FIFO size is less than the current Rx FIFO
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		 * allocation, take space away from current Rx allocation */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		if (tx_space < min_tx_space &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		    ((min_tx_space - tx_space) < pba)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			pba = pba - (min_tx_space - tx_space);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
			/* PCI/PCIx hardware has PBA alignment constraints */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
			switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
			case e1000_82545 ... e1000_82546_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
				pba &= ~(E1000_PBA_8K - 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
			default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
			/* if short on rx space, rx wins and must trump tx
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
			 * adjustment or use Early Receive if available */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
			if (pba < min_rx_space) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
				switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
				case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
					/* ERT enabled in e1000_configure_rx */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
				default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
					pba = min_rx_space;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
				}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	ew32(PBA, pba);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	/* flow control settings */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	/* Set the FC high water mark to 90% of the FIFO size.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 * Required to clear last 3 LSB */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	/* We can't use 90% on small FIFOs because the remainder
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	 * would be less than 1 full frame.  In this case, we size
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	 * it to allow at least a full frame above the high water
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	 *  mark. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	if (pba < E1000_PBA_16K)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
		fc_high_water_mark = (pba * 1024) - 1600;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	hw->fc_high_water = fc_high_water_mark;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	hw->fc_low_water = fc_high_water_mark - 8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	if (hw->mac_type == e1000_80003es2lan)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		hw->fc_pause_time = 0xFFFF;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		hw->fc_pause_time = E1000_FC_PAUSE_TIME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	hw->fc_send_xon = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	hw->fc = hw->original_fc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	/* Allow time for pending master requests to run */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	e1000_reset_hw(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	if (hw->mac_type >= e1000_82544)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
		ew32(WUC, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	if (e1000_init_hw(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		DPRINTK(PROBE, ERR, "Hardware Error\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	e1000_update_mng_vlan(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	if (hw->mac_type >= e1000_82544 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	    hw->mac_type <= e1000_82547_rev_2 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	    hw->autoneg == 1 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		u32 ctrl = er32(CTRL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		/* clear phy power management bit if we are in gig only mode,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		 * which if enabled will attempt negotiation to 100Mb, which
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		 * can cause a loss of link at power off or driver unload */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		ctrl &= ~E1000_CTRL_SWDPIN3;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		ew32(CTRL, ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
	e1000_reset_adaptive(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	e1000_phy_get_info(hw, &adapter->phy_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	if (!adapter->smart_power_down &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	    (hw->mac_type == e1000_82571 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	     hw->mac_type == e1000_82572)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		u16 phy_data = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		/* speed up time to link by disabling smart power down, ignore
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		 * the return value of this function because there is nothing
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		 * different we would do if it failed */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		                   &phy_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		phy_data &= ~IGP02E1000_PM_SPD;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		                    phy_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	e1000_release_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
 *  Dump the eeprom for users having checksum issues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	struct ethtool_eeprom eeprom;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	const struct ethtool_ops *ops = netdev->ethtool_ops;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
	u8 *data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
	u16 csum_old, csum_new = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	eeprom.len = ops->get_eeprom_len(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	eeprom.offset = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	data = kmalloc(eeprom.len, GFP_KERNEL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	if (!data) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		       " data\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	ops->get_eeprom(netdev, &eeprom, data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		csum_new += data[i] + (data[i + 1] << 8);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	csum_new = EEPROM_SUM - csum_new;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	printk(KERN_ERR "/*********************/\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	printk(KERN_ERR "Offset    Values\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	printk(KERN_ERR "========  ======\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	printk(KERN_ERR "Include this output when contacting your support "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	       "provider.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	printk(KERN_ERR "This is not a software error! Something bad "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	       "happened to your hardware or\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	printk(KERN_ERR "EEPROM image. Ignoring this "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	       "problem could result in further problems,\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	       "which is invalid\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	printk(KERN_ERR "and requires you to set the proper MAC "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	       "address manually before continuing\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	printk(KERN_ERR "to enable this network device.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	       "to your hardware vendor\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	printk(KERN_ERR "or Intel Customer Support.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	printk(KERN_ERR "/*********************/\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	kfree(data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
 * @pdev: PCI device information struct
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
 * Return true if an adapter needs ioport resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
static int e1000_is_need_ioport(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	switch (pdev->device) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	case E1000_DEV_ID_82540EM:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	case E1000_DEV_ID_82540EM_LOM:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	case E1000_DEV_ID_82540EP:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	case E1000_DEV_ID_82540EP_LOM:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	case E1000_DEV_ID_82540EP_LP:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	case E1000_DEV_ID_82541EI:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	case E1000_DEV_ID_82541EI_MOBILE:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	case E1000_DEV_ID_82541ER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	case E1000_DEV_ID_82541ER_LOM:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	case E1000_DEV_ID_82541GI:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	case E1000_DEV_ID_82541GI_LF:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	case E1000_DEV_ID_82541GI_MOBILE:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	case E1000_DEV_ID_82544EI_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	case E1000_DEV_ID_82544EI_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	case E1000_DEV_ID_82544GC_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	case E1000_DEV_ID_82544GC_LOM:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	case E1000_DEV_ID_82545EM_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	case E1000_DEV_ID_82545EM_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	case E1000_DEV_ID_82546EB_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	case E1000_DEV_ID_82546EB_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		return true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		return false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
 * e1000_probe - Device Initialization Routine
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
 * @pdev: PCI device information struct
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
 * @ent: entry in e1000_pci_tbl
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 * Returns 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
 * e1000_probe initializes an adapter identified by a pci_dev structure.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
 * The OS initialization, configuring of the adapter private structure,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
 * and a hardware reset occur.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
static int __devinit e1000_probe(struct pci_dev *pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
				 const struct pci_device_id *ent)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	struct net_device *netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	struct e1000_adapter *adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	struct e1000_hw *hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	static int cards_found = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	int i, err, pci_using_dac;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	u16 eeprom_data = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	int bars, need_ioport;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	DECLARE_MAC_BUF(mac);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	/* do not allocate ioport bars when not needed */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	need_ioport = e1000_is_need_ioport(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	if (need_ioport) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
		err = pci_enable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		err = pci_enable_device_mem(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		pci_using_dac = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
			if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
				E1000_ERR("No usable DMA configuration, "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
					  "aborting\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
				goto err_dma;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		pci_using_dac = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		goto err_pci_reg;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	pci_set_master(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	err = -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	if (!netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
		goto err_alloc_etherdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	SET_NETDEV_DEV(netdev, &pdev->dev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	pci_set_drvdata(pdev, netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	adapter->netdev = netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	adapter->pdev = pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	adapter->msg_enable = (1 << debug) - 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	adapter->bars = bars;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	adapter->need_ioport = need_ioport;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	hw->back = adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	err = -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	hw->hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
			      pci_resource_len(pdev, BAR_0));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	if (!hw->hw_addr)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		goto err_ioremap;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	if (adapter->need_ioport) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		for (i = BAR_1; i <= BAR_5; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
			if (pci_resource_len(pdev, i) == 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
				continue;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
				hw->io_base = pci_resource_start(pdev, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	netdev->open = &e1000_open;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	netdev->stop = &e1000_close;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	netdev->hard_start_xmit = &e1000_xmit_frame;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	netdev->get_stats = &e1000_get_stats;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	netdev->set_rx_mode = &e1000_set_rx_mode;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	netdev->set_mac_address = &e1000_set_mac;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	netdev->change_mtu = &e1000_change_mtu;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	netdev->do_ioctl = &e1000_ioctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	e1000_set_ethtool_ops(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	netdev->tx_timeout = &e1000_tx_timeout;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
	netdev->watchdog_timeo = 5 * HZ;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	netdev->vlan_rx_register = e1000_vlan_rx_register;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
#ifdef CONFIG_NET_POLL_CONTROLLER
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	netdev->poll_controller = e1000_netpoll;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	adapter->bd_number = cards_found;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	/* setup the private structure */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	err = e1000_sw_init(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		goto err_sw_init;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	err = -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	/* Flash BAR mapping must happen after e1000_sw_init
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	 * because it depends on mac_type */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	if ((hw->mac_type == e1000_ich8lan) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		hw->flash_address =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
			ioremap(pci_resource_start(pdev, 1),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
				pci_resource_len(pdev, 1));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		if (!hw->flash_address)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			goto err_flashmap;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	if (e1000_check_phy_reset_block(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	if (hw->mac_type >= e1000_82543) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		netdev->features = NETIF_F_SG |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
				   NETIF_F_HW_CSUM |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
				   NETIF_F_HW_VLAN_TX |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
				   NETIF_F_HW_VLAN_RX |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
				   NETIF_F_HW_VLAN_FILTER;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		if (hw->mac_type == e1000_ich8lan)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	if ((hw->mac_type >= e1000_82544) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	   (hw->mac_type != e1000_82547))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		netdev->features |= NETIF_F_TSO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	if (hw->mac_type > e1000_82547_rev_2)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		netdev->features |= NETIF_F_TSO6;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	if (pci_using_dac)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		netdev->features |= NETIF_F_HIGHDMA;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	netdev->features |= NETIF_F_LLTX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	netdev->vlan_features |= NETIF_F_TSO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	netdev->vlan_features |= NETIF_F_TSO6;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	netdev->vlan_features |= NETIF_F_HW_CSUM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	netdev->vlan_features |= NETIF_F_SG;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	/* initialize eeprom parameters */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	if (e1000_init_eeprom_params(hw)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		E1000_ERR("EEPROM initialization failed\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		goto err_eeprom;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	/* before reading the EEPROM, reset the controller to
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	 * put the device in a known good starting state */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	e1000_reset_hw(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	/* make sure the EEPROM is good */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	if (e1000_validate_eeprom_checksum(hw) < 0) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		e1000_dump_eeprom(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		/*
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		 * set MAC address to all zeroes to invalidate and temporary
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		 * disable this device for the user. This blocks regular
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		 * traffic while still permitting ethtool ioctls from reaching
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		 * the hardware as well as allowing the user to run the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		 * interface after manually setting a hw addr using
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		 * `ip set address`
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		memset(hw->mac_addr, 0, netdev->addr_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		/* copy the MAC address out of the EEPROM */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		if (e1000_read_mac_addr(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	/* don't block initalization here due to bad MAC address */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	if (!is_valid_ether_addr(netdev->perm_addr))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	e1000_get_bus_info(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	init_timer(&adapter->tx_fifo_stall_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	init_timer(&adapter->watchdog_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	adapter->watchdog_timer.function = &e1000_watchdog;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	adapter->watchdog_timer.data = (unsigned long) adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	init_timer(&adapter->phy_info_timer);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	adapter->phy_info_timer.function = &e1000_update_phy_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	adapter->phy_info_timer.data = (unsigned long)adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	e1000_check_options(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	/* Initial Wake on LAN setting
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	 * If APM wake is enabled in the EEPROM,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	 * enable the ACPI Magic Packet filter
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	case e1000_82542_rev2_0:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	case e1000_82542_rev2_1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	case e1000_82543:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	case e1000_82544:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		e1000_read_eeprom(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		e1000_read_eeprom(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	case e1000_82546:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	case e1000_82546_rev_3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
			e1000_read_eeprom(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		/* Fall Through */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		e1000_read_eeprom(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	if (eeprom_data & eeprom_apme_mask)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		adapter->eeprom_wol |= E1000_WUFC_MAG;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	/* now that we have the eeprom settings, apply the special cases
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	 * where the eeprom may be wrong or the board simply won't support
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	 * wake on lan on a particular port */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	switch (pdev->device) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	case E1000_DEV_ID_82546GB_PCIE:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		adapter->eeprom_wol = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	case E1000_DEV_ID_82546EB_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	case E1000_DEV_ID_82546GB_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	case E1000_DEV_ID_82571EB_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		/* Wake events only supported on port A for dual fiber
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		 * regardless of eeprom setting */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
			adapter->eeprom_wol = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	case E1000_DEV_ID_82571EB_QUAD_FIBER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	case E1000_DEV_ID_82571PT_QUAD_COPPER:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		/* if quad port adapter, disable WoL on all but port A */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		if (global_quad_port_a != 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			adapter->eeprom_wol = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
			adapter->quad_port_a = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		/* Reset for multiple quad port adapters */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		if (++global_quad_port_a == 4)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
			global_quad_port_a = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	/* initialize the wol settings based on the eeprom settings */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	adapter->wol = adapter->eeprom_wol;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	/* print bus type/speed/width info */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		 "32-bit"));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	printk("%s\n", print_mac(mac, netdev->dev_addr));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	if (hw->bus_type == e1000_bus_type_pci_express) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			"longer be supported by this driver in the future.\n",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
			pdev->vendor, pdev->device);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
			"driver instead.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	/* reset the hardware with the new settings */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	/* If the controller is 82573 and f/w is AMT, do not set
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	 * DRV_LOAD until the interface is up.  For all other cases,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	 * let the f/w know that the h/w is now under the control
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	 * of the driver. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	if (hw->mac_type != e1000_82573 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	    !e1000_check_mng_mode(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		e1000_get_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	/* tell the stack to leave us alone until e1000_open() is called */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	netif_carrier_off(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	strcpy(netdev->name, "eth%d");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	err = register_netdev(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		goto err_register;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	cards_found++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
err_register:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
err_eeprom:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	if (!e1000_check_phy_reset_block(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
		e1000_phy_hw_reset(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	if (hw->flash_address)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		iounmap(hw->flash_address);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
err_flashmap:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	for (i = 0; i < adapter->num_rx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		dev_put(&adapter->polling_netdev[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	kfree(adapter->tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	kfree(adapter->rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	kfree(adapter->polling_netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
err_sw_init:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	iounmap(hw->hw_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
err_ioremap:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	free_netdev(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
err_alloc_etherdev:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	pci_release_selected_regions(pdev, bars);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
err_pci_reg:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
err_dma:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	pci_disable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 * e1000_remove - Device Removal Routine
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
 * @pdev: PCI device information struct
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
 * e1000_remove is called by the PCI subsystem to alert the driver
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 * that it should release a PCI device.  The could be caused by a
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * Hot-Plug event, or because the driver is going to be removed from
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * memory.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
static void __devexit e1000_remove(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	cancel_work_sync(&adapter->reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	e1000_release_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	 * would have already happened in close and is redundant. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	for (i = 0; i < adapter->num_rx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		dev_put(&adapter->polling_netdev[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	unregister_netdev(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	if (!e1000_check_phy_reset_block(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		e1000_phy_hw_reset(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	kfree(adapter->tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	kfree(adapter->rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	kfree(adapter->polling_netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	iounmap(hw->hw_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	if (hw->flash_address)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		iounmap(hw->flash_address);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	pci_release_selected_regions(pdev, adapter->bars);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
	free_netdev(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	pci_disable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
 * @adapter: board private structure to initialize
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
 * e1000_sw_init initializes the Adapter private data structure.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
 * Fields are initialized based on PCI device information and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
 * OS network device settings (MTU size).
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	/* PCI config space info */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	hw->vendor_id = pdev->vendor;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	hw->device_id = pdev->device;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	hw->subsystem_id = pdev->subsystem_device;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	hw->revision_id = pdev->revision;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	hw->max_frame_size = netdev->mtu +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	/* identify the MAC */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	if (e1000_set_mac_type(hw)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		return -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	case e1000_82541:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	case e1000_82547:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	case e1000_82541_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	case e1000_82547_rev_2:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		hw->phy_init_script = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	e1000_set_media_type(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	hw->wait_autoneg_complete = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	hw->tbi_compatibility_en = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	hw->adaptive_ifs = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	/* Copper options */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	if (hw->media_type == e1000_media_type_copper) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		hw->mdix = AUTO_ALL_MODES;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		hw->disable_polarity_correction = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
		hw->master_slave = E1000_MASTER_SLAVE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	adapter->num_tx_queues = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	adapter->num_rx_queues = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	if (e1000_alloc_queues(adapter)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	for (i = 0; i < adapter->num_rx_queues; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
		adapter->polling_netdev[i].priv = adapter;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		dev_hold(&adapter->polling_netdev[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	spin_lock_init(&adapter->tx_queue_lock);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	/* Explicitly disable IRQ since the NIC can be in any state. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	e1000_irq_disable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	spin_lock_init(&adapter->stats_lock);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	set_bit(__E1000_DOWN, &adapter->flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
 * e1000_alloc_queues - Allocate memory for all rings
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * @adapter: board private structure to initialize
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 * We allocate one ring per queue at run-time since we don't know the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 * number of queues at compile-time.  The polling_netdev array is
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 * intended for Multiqueue, but should work fine with a single queue.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	if (!adapter->tx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	if (!adapter->rx_ring) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		kfree(adapter->tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	adapter->polling_netdev = kcalloc(adapter->num_rx_queues,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	                                  sizeof(struct net_device),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	                                  GFP_KERNEL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	if (!adapter->polling_netdev) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		kfree(adapter->tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		kfree(adapter->rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	return E1000_SUCCESS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
 * e1000_open - Called when a network interface is made active
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
 * Returns 0 on success, negative value on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
 * The open entry point is called when a network interface is made
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
 * active by the system (IFF_UP).  At this point all resources needed
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
 * for transmit and receive operations are allocated, the interrupt
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
 * handler is registered with the OS, the watchdog timer is started,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 * and the stack is notified that the interface is ready.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
static int e1000_open(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	int err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	/* disallow open during test */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	if (test_bit(__E1000_TESTING, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		return -EBUSY;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	/* allocate transmit descriptors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	err = e1000_setup_all_tx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		goto err_setup_tx;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	/* allocate receive descriptors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	err = e1000_setup_all_rx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		goto err_setup_rx;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	e1000_power_up_phy(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	if ((hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		e1000_update_mng_vlan(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	/* If AMT is enabled, let the firmware know that the network
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	 * interface is now open */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	if (hw->mac_type == e1000_82573 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	    e1000_check_mng_mode(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		e1000_get_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	/* before we allocate an interrupt, we must be ready to handle it.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	 * as soon as we call pci_request_irq, so we have to setup our
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	 * clean_rx handler before we do so.  */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	e1000_configure(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	err = e1000_request_irq(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		goto err_req_irq;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	/* From here on the code is the same as e1000_up() */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	clear_bit(__E1000_DOWN, &adapter->flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	napi_enable(&adapter->napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	netif_start_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	/* fire a link status change interrupt to start the watchdog */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	ew32(ICS, E1000_ICS_LSC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	return E1000_SUCCESS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
err_req_irq:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	e1000_power_down_phy(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	e1000_free_all_rx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
err_setup_rx:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	e1000_free_all_tx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
err_setup_tx:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
 * e1000_close - Disables a network interface
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
 * Returns 0, this is not allowed to fail
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
 * The close entry point is called when an interface is de-activated
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
 * by the OS.  The hardware is still under the drivers control, but
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
 * needs to be disabled.  A global MAC reset is issued to stop the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
 * hardware, and all transmit and receive resources are freed.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
static int e1000_close(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	e1000_down(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	e1000_power_down_phy(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	e1000_free_irq(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	e1000_free_all_tx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	e1000_free_all_rx_resources(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	/* kill manageability vlan ID if supported, but not if a vlan with
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	 * the same ID is registered on the host OS (let 8021q kill it) */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	if ((hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	     !(adapter->vlgrp &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	/* If AMT is enabled, let the firmware know that the network
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	 * interface is now closed */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
	if (hw->mac_type == e1000_82573 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	    e1000_check_mng_mode(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
 * @adapter: address of board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
 * @start: address of beginning of memory
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
 * @len: length of memory
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
				  unsigned long len)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	unsigned long begin = (unsigned long)start;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	unsigned long end = begin + len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	/* First rev 82545 and 82546 need to not allow any memory
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	 * write location to cross 64k boundary due to errata 23 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	if (hw->mac_type == e1000_82545 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	    hw->mac_type == e1000_82546) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	return true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
 * @txdr:    tx descriptor ring (for a specific queue) to setup
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
 * Return 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
				    struct e1000_tx_ring *txdr)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	int size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	size = sizeof(struct e1000_buffer) * txdr->count;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	txdr->buffer_info = vmalloc(size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	if (!txdr->buffer_info) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		"Unable to allocate memory for the transmit descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	memset(txdr->buffer_info, 0, size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	/* round up to nearest 4K */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
	txdr->size = ALIGN(txdr->size, 4096);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	if (!txdr->desc) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
setup_tx_desc_die:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		vfree(txdr->buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		"Unable to allocate memory for the transmit descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	/* Fix for errata 23, can't cross 64kB boundary */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		void *olddesc = txdr->desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		dma_addr_t olddma = txdr->dma;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
				     "at %p\n", txdr->size, txdr->desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		/* Try again, without freeing the previous */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		/* Failed allocation, critical failure */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		if (!txdr->desc) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			goto setup_tx_desc_die;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			/* give up */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
			pci_free_consistent(pdev, txdr->size, txdr->desc,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
					    txdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
			DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
				"Unable to allocate aligned memory "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
				"for the transmit descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
			vfree(txdr->buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
			return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
			/* Free old allocation, new allocation was successful */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	memset(txdr->desc, 0, txdr->size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	txdr->next_to_use = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	txdr->next_to_clean = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	spin_lock_init(&txdr->tx_lock);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
 * 				  (Descriptors) for all queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
 * Return 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	int i, err = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	for (i = 0; i < adapter->num_tx_queues; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
				"Allocation for Tx Queue %u failed\n", i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			for (i-- ; i >= 0; i--)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
				e1000_free_tx_resources(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
							&adapter->tx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
 * Configure the Tx unit of the MAC after a reset.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
static void e1000_configure_tx(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	u64 tdba;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	u32 tdlen, tctl, tipg, tarc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	u32 ipgr1, ipgr2;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	/* Setup the HW Tx Head and Tail descriptor pointers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	switch (adapter->num_tx_queues) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	case 1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		tdba = adapter->tx_ring[0].dma;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		tdlen = adapter->tx_ring[0].count *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
			sizeof(struct e1000_tx_desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		ew32(TDLEN, tdlen);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		ew32(TDBAH, (tdba >> 32));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
		ew32(TDT, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		ew32(TDH, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	/* Set the default values for the Tx Inter Packet Gap timer */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	if (hw->mac_type <= e1000_82547_rev_2 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	    (hw->media_type == e1000_media_type_fiber ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	     hw->media_type == e1000_media_type_internal_serdes))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	case e1000_82542_rev2_0:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	case e1000_82542_rev2_1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		tipg = DEFAULT_82542_TIPG_IPGT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	ew32(TIPG, tipg);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	/* Set the Tx Interrupt Delay register */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	ew32(TIDV, adapter->tx_int_delay);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	if (hw->mac_type >= e1000_82540)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		ew32(TADV, adapter->tx_abs_int_delay);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	/* Program the Transmit Control Register */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	tctl = er32(TCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	tctl &= ~E1000_TCTL_CT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		tarc = er32(TARC0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		/* set the speed mode bit, we'll clear it if we're not at
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		 * gigabit link later */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		tarc |= (1 << 21);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		ew32(TARC0, tarc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	} else if (hw->mac_type == e1000_80003es2lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
		tarc = er32(TARC0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		tarc |= 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		ew32(TARC0, tarc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		tarc = er32(TARC1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		tarc |= 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		ew32(TARC1, tarc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	e1000_config_collision_dist(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	/* Setup Transmit Descriptor Settings for eop descriptor */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	/* only set IDE if we are delaying interrupts using the timers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	if (adapter->tx_int_delay)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	if (hw->mac_type < e1000_82543)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	/* Cache if we're 82544 running in PCI-X because we'll
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	 * need this to apply a workaround later in the send path. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	if (hw->mac_type == e1000_82544 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	    hw->bus_type == e1000_bus_type_pcix)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		adapter->pcix_82544 = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	ew32(TCTL, tctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
 * Returns 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
				    struct e1000_rx_ring *rxdr)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	int size, desc_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	size = sizeof(struct e1000_buffer) * rxdr->count;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	rxdr->buffer_info = vmalloc(size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	if (!rxdr->buffer_info) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		"Unable to allocate memory for the receive descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	memset(rxdr->buffer_info, 0, size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	if (hw->mac_type <= e1000_82547_rev_2)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		desc_len = sizeof(struct e1000_rx_desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		desc_len = sizeof(union e1000_rx_desc_packet_split);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	/* Round up to nearest 4K */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	rxdr->size = rxdr->count * desc_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	rxdr->size = ALIGN(rxdr->size, 4096);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	if (!rxdr->desc) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		"Unable to allocate memory for the receive descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
setup_rx_desc_die:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		vfree(rxdr->buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		return -ENOMEM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	/* Fix for errata 23, can't cross 64kB boundary */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		void *olddesc = rxdr->desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		dma_addr_t olddma = rxdr->dma;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
				     "at %p\n", rxdr->size, rxdr->desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
		/* Try again, without freeing the previous */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		/* Failed allocation, critical failure */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		if (!rxdr->desc) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
			DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
				"Unable to allocate memory "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
				"for the receive descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
			goto setup_rx_desc_die;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
			/* give up */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
					    rxdr->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
			DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
				"Unable to allocate aligned memory "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
				"for the receive descriptor ring\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
			goto setup_rx_desc_die;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
			/* Free old allocation, new allocation was successful */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	memset(rxdr->desc, 0, rxdr->size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	rxdr->next_to_clean = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	rxdr->next_to_use = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
 * 				  (Descriptors) for all queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
 * Return 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	int i, err = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	for (i = 0; i < adapter->num_rx_queues; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
			DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
				"Allocation for Rx Queue %u failed\n", i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
			for (i-- ; i >= 0; i--)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
				e1000_free_rx_resources(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
							&adapter->rx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
 * e1000_setup_rctl - configure the receive control registers
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
 * @adapter: Board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
static void e1000_setup_rctl(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	u32 rctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	if (hw->tbi_compatibility_on == 1)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		rctl |= E1000_RCTL_SBP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		rctl &= ~E1000_RCTL_SBP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
		rctl &= ~E1000_RCTL_LPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
		rctl |= E1000_RCTL_LPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	/* Setup buffer sizes */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	rctl &= ~E1000_RCTL_SZ_4096;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	rctl |= E1000_RCTL_BSEX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	switch (adapter->rx_buffer_len) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		case E1000_RXBUFFER_256:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
			rctl |= E1000_RCTL_SZ_256;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
			rctl &= ~E1000_RCTL_BSEX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		case E1000_RXBUFFER_512:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
			rctl |= E1000_RCTL_SZ_512;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
			rctl &= ~E1000_RCTL_BSEX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		case E1000_RXBUFFER_1024:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
			rctl |= E1000_RCTL_SZ_1024;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
			rctl &= ~E1000_RCTL_BSEX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		case E1000_RXBUFFER_2048:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
			rctl |= E1000_RCTL_SZ_2048;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
			rctl &= ~E1000_RCTL_BSEX;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		case E1000_RXBUFFER_4096:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			rctl |= E1000_RCTL_SZ_4096;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		case E1000_RXBUFFER_8192:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
			rctl |= E1000_RCTL_SZ_8192;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		case E1000_RXBUFFER_16384:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			rctl |= E1000_RCTL_SZ_16384;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
 * Configure the Rx unit of the MAC after a reset.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
static void e1000_configure_rx(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	u64 rdba;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	u32 rdlen, rctl, rxcsum, ctrl_ext;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	rdlen = adapter->rx_ring[0].count *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		sizeof(struct e1000_rx_desc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	adapter->clean_rx = e1000_clean_rx_irq;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	/* disable receives while setting up the descriptors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	/* set the Receive Delay Timer Register */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	ew32(RDTR, adapter->rx_int_delay);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	if (hw->mac_type >= e1000_82540) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		ew32(RADV, adapter->rx_abs_int_delay);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
		if (adapter->itr_setting != 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
			ew32(ITR, 1000000000 / (adapter->itr * 256));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	if (hw->mac_type >= e1000_82571) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		ctrl_ext = er32(CTRL_EXT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		/* Reset delay timers after every interrupt */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
		/* Auto-Mask interrupts upon ICR access */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
		ctrl_ext |= E1000_CTRL_EXT_IAME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		ew32(IAM, 0xffffffff);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
		ew32(CTRL_EXT, ctrl_ext);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
		E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	 * the Base and Length of the Rx Descriptor Ring */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	switch (adapter->num_rx_queues) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	case 1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		rdba = adapter->rx_ring[0].dma;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		ew32(RDLEN, rdlen);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		ew32(RDBAH, (rdba >> 32));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		ew32(RDT, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		ew32(RDH, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	if (hw->mac_type >= e1000_82543) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		rxcsum = er32(RXCSUM);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
		if (adapter->rx_csum)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
			rxcsum |= E1000_RXCSUM_TUOFL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
			/* don't need to clear IPPCSE as it defaults to 0 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
			rxcsum &= ~E1000_RXCSUM_TUOFL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
		ew32(RXCSUM, rxcsum);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	/* Enable Receives */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
 * e1000_free_tx_resources - Free Tx Resources per Queue
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
 * @tx_ring: Tx descriptor ring for a specific queue
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
 * Free all transmit software resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
				    struct e1000_tx_ring *tx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
	e1000_clean_tx_ring(adapter, tx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	vfree(tx_ring->buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	tx_ring->buffer_info = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	tx_ring->desc = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
 * Free all transmit software resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	for (i = 0; i < adapter->num_tx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
					     struct e1000_buffer *buffer_info)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	if (buffer_info->dma) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		pci_unmap_page(adapter->pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
				buffer_info->dma,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
				buffer_info->length,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
				PCI_DMA_TODEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
		buffer_info->dma = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	if (buffer_info->skb) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		dev_kfree_skb_any(buffer_info->skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
		buffer_info->skb = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	/* buffer_info must be completely set up in the transmit path */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
 * e1000_clean_tx_ring - Free Tx Buffers
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
 * @tx_ring: ring to be cleaned
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
				struct e1000_tx_ring *tx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	unsigned long size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	/* Free all the Tx ring sk_buffs */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	for (i = 0; i < tx_ring->count; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	size = sizeof(struct e1000_buffer) * tx_ring->count;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	memset(tx_ring->buffer_info, 0, size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	/* Zero out the descriptor ring */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	memset(tx_ring->desc, 0, tx_ring->size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	tx_ring->next_to_use = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	tx_ring->next_to_clean = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	tx_ring->last_tx_tso = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	writel(0, hw->hw_addr + tx_ring->tdh);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	writel(0, hw->hw_addr + tx_ring->tdt);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	for (i = 0; i < adapter->num_tx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * e1000_free_rx_resources - Free Rx Resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 * @rx_ring: ring to clean the resources from
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
 * Free all receive software resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
				    struct e1000_rx_ring *rx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	e1000_clean_rx_ring(adapter, rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	vfree(rx_ring->buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	rx_ring->buffer_info = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	rx_ring->desc = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
 * Free all receive software resources
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
	for (i = 0; i < adapter->num_rx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
 * @rx_ring: ring to free buffers from
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
				struct e1000_rx_ring *rx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	unsigned long size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	/* Free all the Rx ring sk_buffs */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	for (i = 0; i < rx_ring->count; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		buffer_info = &rx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		if (buffer_info->skb) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
			pci_unmap_single(pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
					 buffer_info->dma,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
					 buffer_info->length,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
					 PCI_DMA_FROMDEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
			dev_kfree_skb(buffer_info->skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			buffer_info->skb = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	size = sizeof(struct e1000_buffer) * rx_ring->count;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	memset(rx_ring->buffer_info, 0, size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	/* Zero out the descriptor ring */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	memset(rx_ring->desc, 0, rx_ring->size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	rx_ring->next_to_clean = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	rx_ring->next_to_use = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	writel(0, hw->hw_addr + rx_ring->rdh);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	writel(0, hw->hw_addr + rx_ring->rdt);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	for (i = 0; i < adapter->num_rx_queues; i++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
 * and memory write and invalidate disabled for certain operations
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	u32 rctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	e1000_pci_clear_mwi(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	rctl |= E1000_RCTL_RST;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	mdelay(5);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	if (netif_running(netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
		e1000_clean_all_rx_rings(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	u32 rctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	rctl &= ~E1000_RCTL_RST;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	mdelay(5);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		e1000_pci_set_mwi(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
	if (netif_running(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		/* No need to loop, because 82542 supports only 1 queue */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
		e1000_configure_rx(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
		adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 * e1000_set_mac - Change the Ethernet Address of the NIC
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
 * @p: pointer to an address structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
 * Returns 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
static int e1000_set_mac(struct net_device *netdev, void *p)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	struct sockaddr *addr = p;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	if (!is_valid_ether_addr(addr->sa_data))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
		return -EADDRNOTAVAIL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	/* 82542 2.0 needs to be in reset to write receive address registers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	if (hw->mac_type == e1000_82542_rev2_0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		e1000_enter_82542_rst(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	e1000_rar_set(hw, hw->mac_addr, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	/* With 82571 controllers, LAA may be overwritten (with the default)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	 * due to controller reset from the other port. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	if (hw->mac_type == e1000_82571) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
		/* activate the work around */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
		hw->laa_is_present = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		/* Hold a copy of the LAA in RAR[14] This is done so that
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
		 * between the time RAR[0] gets clobbered  and the time it
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
		 * of the RARs and no incoming packets directed to this port
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
		 * are dropped. Eventaully the LAA will be in RAR[0] and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		 * RAR[14] */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		e1000_rar_set(hw, hw->mac_addr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
					E1000_RAR_ENTRIES - 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	if (hw->mac_type == e1000_82542_rev2_0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		e1000_leave_82542_rst(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
 * The set_rx_mode entry point is called whenever the unicast or multicast
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
 * address lists or the network interface flags are updated. This routine is
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
 * responsible for configuring the hardware for proper unicast, multicast,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
 * promiscuous mode, and all-multi behavior.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
static void e1000_set_rx_mode(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	struct dev_addr_list *uc_ptr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	struct dev_addr_list *mc_ptr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	u32 rctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	u32 hash_value;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	int i, rar_entries = E1000_RAR_ENTRIES;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
				E1000_NUM_MTA_REGISTERS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	if (hw->mac_type == e1000_ich8lan)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	/* reserve RAR[14] for LAA over-write work-around */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	if (hw->mac_type == e1000_82571)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		rar_entries--;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	/* Check for Promiscuous and All Multicast modes */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	if (netdev->flags & IFF_PROMISC) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		rctl &= ~E1000_RCTL_VFE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
		if (netdev->flags & IFF_ALLMULTI) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
			rctl |= E1000_RCTL_MPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			rctl &= ~E1000_RCTL_MPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		if (adapter->hw.mac_type != e1000_ich8lan)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
			rctl |= E1000_RCTL_VFE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	uc_ptr = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	if (netdev->uc_count > rar_entries - 1) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
		rctl |= E1000_RCTL_UPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	} else if (!(netdev->flags & IFF_PROMISC)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		rctl &= ~E1000_RCTL_UPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		uc_ptr = netdev->uc_list;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	/* 82542 2.0 needs to be in reset to write receive address registers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	if (hw->mac_type == e1000_82542_rev2_0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		e1000_enter_82542_rst(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	/* load the first 14 addresses into the exact filters 1-14. Unicast
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	 * addresses take precedence to avoid disabling unicast filtering
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	 * when possible.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	 * RAR 0 is used for the station MAC adddress
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	 * if there are not 14 addresses, go ahead and clear the filters
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	 * -- with 82571 controllers only 0-13 entries are filled here
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	mc_ptr = netdev->mc_list;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	for (i = 1; i < rar_entries; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		if (uc_ptr) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			e1000_rar_set(hw, uc_ptr->da_addr, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
			uc_ptr = uc_ptr->next;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		} else if (mc_ptr) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			e1000_rar_set(hw, mc_ptr->da_addr, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
			mc_ptr = mc_ptr->next;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
			E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
			E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	WARN_ON(uc_ptr != NULL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	/* clear the old settings from the multicast hash table */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	for (i = 0; i < mta_reg_count; i++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	/* load any remaining addresses into the hash table */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		e1000_mta_set(hw, hash_value);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	if (hw->mac_type == e1000_82542_rev2_0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		e1000_leave_82542_rst(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
/* Need to wait a few seconds after link up to get diagnostic information from
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
 * the phy */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
static void e1000_update_phy_info(unsigned long data)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	e1000_phy_get_info(hw, &adapter->phy_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
 * e1000_82547_tx_fifo_stall - Timer Call-back
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
 * @data: pointer to adapter cast into an unsigned long
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
static void e1000_82547_tx_fifo_stall(unsigned long data)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	u32 tctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	if (atomic_read(&adapter->tx_fifo_stall)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		if ((er32(TDT) == er32(TDH)) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		   (er32(TDFT) == er32(TDFH)) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		   (er32(TDFTS) == er32(TDFHS))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			tctl = er32(TCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
			ew32(TDFT, adapter->tx_head_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			ew32(TDFH, adapter->tx_head_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
			ew32(TDFTS, adapter->tx_head_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
			ew32(TDFHS, adapter->tx_head_addr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
			ew32(TCTL, tctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
			E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
			adapter->tx_fifo_head = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
			atomic_set(&adapter->tx_fifo_stall, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
			netif_wake_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
 * e1000_watchdog - Timer Call-back
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
 * @data: pointer to adapter cast into an unsigned long
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
static void e1000_watchdog(unsigned long data)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	struct e1000_tx_ring *txdr = adapter->tx_ring;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
	u32 link, tctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	s32 ret_val;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	ret_val = e1000_check_for_link(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	if ((ret_val == E1000_ERR_PHY) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	    (hw->phy_type == e1000_phy_igp_3) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
		/* See e1000_kumeran_lock_loss_workaround() */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		DPRINTK(LINK, INFO,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			"Gigabit has been disabled, downgrading speed\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	if (hw->mac_type == e1000_82573) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		e1000_enable_tx_pkt_filtering(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		if (adapter->mng_vlan_id != hw->mng_cookie.vlan_id)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
			e1000_update_mng_vlan(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	if ((hw->media_type == e1000_media_type_internal_serdes) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
	   !(er32(TXCW) & E1000_TXCW_ANE))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		link = !hw->serdes_link_down;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		link = er32(STATUS) & E1000_STATUS_LU;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	if (link) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		if (!netif_carrier_ok(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
			u32 ctrl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			bool txb2b = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
			e1000_get_speed_and_duplex(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
			                           &adapter->link_speed,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			                           &adapter->link_duplex);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
			ctrl = er32(CTRL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
			DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s, "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			        "Flow Control: %s\n",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			        adapter->link_speed,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			        adapter->link_duplex == FULL_DUPLEX ?
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			        "Full Duplex" : "Half Duplex",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			/* tweak tx_queue_len according to speed/duplex
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			 * and adjust the timeout factor */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			netdev->tx_queue_len = adapter->tx_queue_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
			adapter->tx_timeout_factor = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			switch (adapter->link_speed) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
			case SPEED_10:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
				txb2b = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
				netdev->tx_queue_len = 10;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
				adapter->tx_timeout_factor = 8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
			case SPEED_100:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
				txb2b = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
				netdev->tx_queue_len = 100;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
				/* maybe add some timeout factor ? */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
			if ((hw->mac_type == e1000_82571 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
			     hw->mac_type == e1000_82572) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			    !txb2b) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
				u32 tarc0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
				tarc0 = er32(TARC0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
				tarc0 &= ~(1 << 21);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
				ew32(TARC0, tarc0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
			/* disable TSO for pcie and 10/100 speeds, to avoid
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
			 * some hardware issues */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
			if (!adapter->tso_force &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
			    hw->bus_type == e1000_bus_type_pci_express){
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
				switch (adapter->link_speed) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
				case SPEED_10:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
				case SPEED_100:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
					DPRINTK(PROBE,INFO,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
				        "10/100 speed: disabling TSO\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
					netdev->features &= ~NETIF_F_TSO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
					netdev->features &= ~NETIF_F_TSO6;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
				case SPEED_1000:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
					netdev->features |= NETIF_F_TSO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
					netdev->features |= NETIF_F_TSO6;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
				default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
					/* oops */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
				}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
			/* enable transmits in the hardware, need to do this
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			 * after setting TARC0 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
			tctl = er32(TCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			tctl |= E1000_TCTL_EN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			ew32(TCTL, tctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
			netif_carrier_on(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
			netif_wake_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
			adapter->smartspeed = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			/* make sure the receive unit is started */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
			if (hw->rx_needs_kicking) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
				u32 rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
				ew32(RCTL, rctl | E1000_RCTL_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
		if (netif_carrier_ok(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
			adapter->link_speed = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
			adapter->link_duplex = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
			DPRINTK(LINK, INFO, "NIC Link is Down\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
			netif_carrier_off(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
			netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
			mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
			/* 80003ES2LAN workaround--
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
			 * For packet buffer work-around on link down event;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
			 * disable receives in the ISR and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
			 * reset device here in the watchdog
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
			 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
			if (hw->mac_type == e1000_80003es2lan)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
				/* reset device */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
				schedule_work(&adapter->reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
		e1000_smartspeed(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	e1000_update_stats(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	adapter->tpt_old = adapter->stats.tpt;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	adapter->colc_old = adapter->stats.colc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	adapter->gorcl_old = adapter->stats.gorcl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	adapter->gotcl_old = adapter->stats.gotcl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	e1000_update_adaptive(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	if (!netif_carrier_ok(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
			/* We've lost link, so the controller stops DMA,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
			 * but we've got queued Tx work that's never going
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
			 * to get done, so reset controller to flush Tx.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
			 * (Do the reset outside of interrupt context). */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			adapter->tx_timeout_count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			schedule_work(&adapter->reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	/* Cause software interrupt to ensure rx ring is cleaned */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	ew32(ICS, E1000_ICS_RXDMT0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	/* Force detection of hung controller every watchdog period */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	adapter->detect_tx_hung = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	/* With 82571 controllers, LAA may be overwritten due to controller
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	if (hw->mac_type == e1000_82571 && hw->laa_is_present)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		e1000_rar_set(hw, hw->mac_addr, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	/* Reset the timer */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
enum latency_range {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	lowest_latency = 0,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	low_latency = 1,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	bulk_latency = 2,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	latency_invalid = 255
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
};
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
 * e1000_update_itr - update the dynamic ITR value based on statistics
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
 *      Stores a new ITR value based on packets and byte
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
 *      counts during the last interrupt.  The advantage of per interrupt
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
 *      computation is faster updates and more accurate ITR for the current
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
 *      traffic pattern.  Constants in this function were computed
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
 *      based on theoretical maximum wire speed and thresholds were set based
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
 *      on testing data as well as attempting to minimize response time
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
 *      while increasing bulk throughput.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
 *      this functionality is controlled by the InterruptThrottleRate module
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
 *      parameter (see e1000_param.c)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
 * @adapter: pointer to adapter
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
 * @itr_setting: current adapter->itr
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
 * @packets: the number of packets during this measurement interval
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
 * @bytes: the number of bytes during this measurement interval
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
				     u16 itr_setting, int packets, int bytes)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	unsigned int retval = itr_setting;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	if (unlikely(hw->mac_type < e1000_82540))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		goto update_itr_done;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
	if (packets == 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
		goto update_itr_done;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	switch (itr_setting) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	case lowest_latency:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		/* jumbo frames get bulk treatment*/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		if (bytes/packets > 8000)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
			retval = bulk_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		else if ((packets < 5) && (bytes > 512))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
			retval = low_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	case low_latency:  /* 50 usec aka 20000 ints/s */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		if (bytes > 10000) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			/* jumbo frames need bulk latency setting */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
			if (bytes/packets > 8000)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
				retval = bulk_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			else if ((packets < 10) || ((bytes/packets) > 1200))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
				retval = bulk_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
			else if ((packets > 35))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
				retval = lowest_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		} else if (bytes/packets > 2000)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
			retval = bulk_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		else if (packets <= 2 && bytes < 512)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
			retval = lowest_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	case bulk_latency: /* 250 usec aka 4000 ints/s */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		if (bytes > 25000) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
			if (packets > 35)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
				retval = low_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
		} else if (bytes < 6000) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
			retval = low_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
update_itr_done:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	return retval;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
static void e1000_set_itr(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	u16 current_itr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	u32 new_itr = adapter->itr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	if (unlikely(hw->mac_type < e1000_82540))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	if (unlikely(adapter->link_speed != SPEED_1000)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		current_itr = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
		new_itr = 4000;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		goto set_itr_now;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	adapter->tx_itr = e1000_update_itr(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	                            adapter->tx_itr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	                            adapter->total_tx_packets,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	                            adapter->total_tx_bytes);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		adapter->tx_itr = low_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	adapter->rx_itr = e1000_update_itr(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	                            adapter->rx_itr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	                            adapter->total_rx_packets,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	                            adapter->total_rx_bytes);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		adapter->rx_itr = low_latency;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	switch (current_itr) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	/* counts and packets in update_itr are dependent on these numbers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	case lowest_latency:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		new_itr = 70000;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
	case low_latency:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		new_itr = 20000; /* aka hwitr = ~200 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
	case bulk_latency:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		new_itr = 4000;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
set_itr_now:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	if (new_itr != adapter->itr) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		/* this attempts to bias the interrupt rate towards Bulk
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		 * by adding intermediate steps when interrupt rate is
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		 * increasing */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		new_itr = new_itr > adapter->itr ?
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		             min(adapter->itr + (new_itr >> 2), new_itr) :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		             new_itr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		adapter->itr = new_itr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		ew32(ITR, 1000000000 / (new_itr * 256));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
#define E1000_TX_FLAGS_CSUM		0x00000001
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
#define E1000_TX_FLAGS_VLAN		0x00000002
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
#define E1000_TX_FLAGS_TSO		0x00000004
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
#define E1000_TX_FLAGS_IPV4		0x00000008
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
#define E1000_TX_FLAGS_VLAN_SHIFT	16
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
static int e1000_tso(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	struct e1000_context_desc *context_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	u32 cmd_length = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	u16 ipcse = 0, tucse, mss;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	int err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	if (skb_is_gso(skb)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		if (skb_header_cloned(skb)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
			if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
				return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
		mss = skb_shinfo(skb)->gso_size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		if (skb->protocol == htons(ETH_P_IP)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
			struct iphdr *iph = ip_hdr(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
			iph->tot_len = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
			iph->check = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
								 iph->daddr, 0,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
								 IPPROTO_TCP,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
								 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
			cmd_length = E1000_TXD_CMD_IP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
			ipcse = skb_transport_offset(skb) - 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
			ipv6_hdr(skb)->payload_len = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			tcp_hdr(skb)->check =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
						 &ipv6_hdr(skb)->daddr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
						 0, IPPROTO_TCP, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
			ipcse = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		ipcss = skb_network_offset(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		tucss = skb_transport_offset(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		tucse = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		i = tx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		context_desc->upper_setup.tcp_fields.tucss = tucss;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
		context_desc->upper_setup.tcp_fields.tucso = tucso;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		buffer_info->time_stamp = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		buffer_info->next_to_watch = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		if (++i == tx_ring->count) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		tx_ring->next_to_use = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		return true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	return false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
static bool e1000_tx_csum(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	struct e1000_context_desc *context_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	u8 css;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	u32 cmd_len = E1000_TXD_CMD_DEXT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	if (skb->ip_summed != CHECKSUM_PARTIAL)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		return false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	switch (skb->protocol) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	case __constant_htons(ETH_P_IP):
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
			cmd_len |= E1000_TXD_CMD_TCP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	case __constant_htons(ETH_P_IPV6):
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		/* XXX not handling all IPV6 headers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
			cmd_len |= E1000_TXD_CMD_TCP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
		if (unlikely(net_ratelimit()))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
			DPRINTK(DRV, WARNING,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
			        "checksum_partial proto=%x!\n", skb->protocol);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	css = skb_transport_offset(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	i = tx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	context_desc->lower_setup.ip_config = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	context_desc->upper_setup.tcp_fields.tucss = css;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	context_desc->upper_setup.tcp_fields.tucso =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		css + skb->csum_offset;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	context_desc->upper_setup.tcp_fields.tucse = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	context_desc->tcp_seg_setup.data = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	buffer_info->time_stamp = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	buffer_info->next_to_watch = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	if (unlikely(++i == tx_ring->count)) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	tx_ring->next_to_use = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	return true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
#define E1000_MAX_TXD_PWR	12
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
static int e1000_tx_map(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
			struct e1000_tx_ring *tx_ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
			struct sk_buff *skb, unsigned int first,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
			unsigned int max_per_txd, unsigned int nr_frags,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
			unsigned int mss)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	unsigned int len = skb->len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	unsigned int offset = 0, size, count = 0, i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	unsigned int f;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	len -= skb->data_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	i = tx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	while (len) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
		buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		size = min(len, max_per_txd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		/* Workaround for Controller erratum --
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		 * descriptor for non-tso packet in a linear SKB that follows a
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		 * tso gets written back prematurely before the data is fully
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		 * DMA'd to the controller */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		if (!skb->data_len && tx_ring->last_tx_tso &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		    !skb_is_gso(skb)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
			tx_ring->last_tx_tso = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
			size -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		/* Workaround for premature desc write-backs
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		 * in TSO mode.  Append 4-byte sentinel desc */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
		if (unlikely(mss && !nr_frags && size == len && size > 8))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
			size -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		/* work-around for errata 10 and it applies
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		 * to all controllers in PCI-X mode
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		 * The fix is to make sure that the first descriptor of a
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		                (size > 2015) && count == 0))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		        size = 2015;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		 * terminating buffers within evenly-aligned dwords. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		if (unlikely(adapter->pcix_82544 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		   size > 4))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
			size -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
		buffer_info->length = size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		buffer_info->dma =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
			pci_map_single(adapter->pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
				skb->data + offset,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
				size,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
				PCI_DMA_TODEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		buffer_info->time_stamp = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		buffer_info->next_to_watch = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		len -= size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		offset += size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		if (unlikely(++i == tx_ring->count)) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	for (f = 0; f < nr_frags; f++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		struct skb_frag_struct *frag;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		frag = &skb_shinfo(skb)->frags[f];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
		len = frag->size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
		offset = frag->page_offset;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		while (len) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
			buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
			size = min(len, max_per_txd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
			/* Workaround for premature desc write-backs
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
			 * in TSO mode.  Append 4-byte sentinel desc */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
				size -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
			/* Workaround for potential 82544 hang in PCI-X.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
			 * Avoid terminating buffers within evenly-aligned
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
			 * dwords. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
			if (unlikely(adapter->pcix_82544 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
			   size > 4))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
				size -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
			buffer_info->length = size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			buffer_info->dma =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
				pci_map_page(adapter->pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
					frag->page,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
					offset,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
					size,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
					PCI_DMA_TODEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
			buffer_info->time_stamp = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
			buffer_info->next_to_watch = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
			len -= size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
			offset += size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
			count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
			if (unlikely(++i == tx_ring->count)) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	tx_ring->buffer_info[i].skb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	tx_ring->buffer_info[first].next_to_watch = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	return count;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
static void e1000_tx_queue(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
			   struct e1000_tx_ring *tx_ring, int tx_flags,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
			   int count)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	struct e1000_tx_desc *tx_desc = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		             E1000_TXD_CMD_TSE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
		txd_lower |= E1000_TXD_CMD_VLE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	i = tx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	while (count--) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		tx_desc = E1000_TX_DESC(*tx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		tx_desc->lower.data =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
			cpu_to_le32(txd_lower | buffer_info->length);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		tx_desc->upper.data = cpu_to_le32(txd_upper);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		if (unlikely(++i == tx_ring->count)) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	/* Force memory writes to complete before letting h/w
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	 * know there are new descriptors to fetch.  (Only
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	 * applicable for weak-ordered memory model archs,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	 * such as IA-64). */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	wmb();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	tx_ring->next_to_use = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	writel(i, hw->hw_addr + tx_ring->tdt);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	/* we need this if more than one processor can write to our tail
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	 * at a time, it syncronizes IO on IA64/Altix systems */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	mmiowb();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
 * 82547 workaround to avoid controller hang in half-duplex environment.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
 * The workaround is to avoid queuing a large packet that would span
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
 * the internal Tx FIFO ring boundary by notifying the stack to resend
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
 * to the beginning of the Tx FIFO.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
#define E1000_FIFO_HDR			0x10
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
#define E1000_82547_PAD_LEN		0x3E0
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
				       struct sk_buff *skb)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	if (adapter->link_duplex != HALF_DUPLEX)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		goto no_fifo_stall_required;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	if (atomic_read(&adapter->tx_fifo_stall))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		return 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
		atomic_set(&adapter->tx_fifo_stall, 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		return 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
no_fifo_stall_required:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	adapter->tx_fifo_head += skb_fifo_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
#define MINIMUM_DHCP_PACKET_SIZE 282
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
				    struct sk_buff *skb)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	struct e1000_hw *hw =  &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	u16 length, offset;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	if (vlan_tx_tag_present(skb)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
			( hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		struct ethhdr *eth = (struct ethhdr *)skb->data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		if ((htons(ETH_P_IP) == eth->h_proto)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
			const struct iphdr *ip =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
				(struct iphdr *)((u8 *)skb->data+14);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
			if (IPPROTO_UDP == ip->protocol) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
				struct udphdr *udp =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
					(struct udphdr *)((u8 *)ip +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
						(ip->ihl << 2));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
				if (ntohs(udp->dest) == 67) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
					offset = (u8 *)udp + 8 - skb->data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
					length = skb->len - offset;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
					return e1000_mng_write_dhcp_info(hw,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
							(u8 *)udp + 8,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
							length);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
				}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	/* Herbert's original patch had:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	 *  smp_mb__after_netif_stop_queue();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	 * but since that doesn't exist yet, just open code it. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	smp_mb();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	/* We need to check again in a case another CPU has just
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	 * made room available. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
		return -EBUSY;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	/* A reprieve! */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	netif_start_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	++adapter->restart_queue;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
static int e1000_maybe_stop_tx(struct net_device *netdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
                               struct e1000_tx_ring *tx_ring, int size)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	return __e1000_maybe_stop_tx(netdev, size);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	struct e1000_tx_ring *tx_ring;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	unsigned int tx_flags = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	unsigned int len = skb->len - skb->data_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	unsigned long flags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	unsigned int nr_frags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	unsigned int mss;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	int count = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	int tso;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	unsigned int f;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	/* This goes back to the question of how to logically map a tx queue
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	 * to a flow.  Right now, performance is impacted slightly negatively
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	 * if using multiple tx queues.  If the stack breaks away from a
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	 * single qdisc implementation, we can look at this again. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	tx_ring = adapter->tx_ring;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	if (unlikely(skb->len <= 0)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		dev_kfree_skb_any(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		return NETDEV_TX_OK;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	/* 82571 and newer doesn't need the workaround that limited descriptor
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	 * length to 4kB */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	if (hw->mac_type >= e1000_82571)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		max_per_txd = 8192;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	mss = skb_shinfo(skb)->gso_size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	/* The controller does a simple calculation to
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	 * make sure there is enough room in the FIFO before
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	 * initiating the DMA for each buffer.  The calc is:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	 * 4 = ceil(buffer len/mss).  To make sure we don't
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	 * overrun the FIFO, adjust the max buffer len if mss
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	 * drops. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	if (mss) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		u8 hdr_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		max_per_txd = min(mss << 2, max_per_txd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
		max_txd_pwr = fls(max_per_txd) - 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		* points to just header, pull a few bytes of payload from
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		* frags into skb->data */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
		if (skb->data_len && hdr_len == len) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
			switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
				unsigned int pull_size;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
			case e1000_82544:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
				/* Make sure we have room to chop off 4 bytes,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
				 * and that the end alignment will work out to
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
				 * this hardware's requirements
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
				 * NOTE: this is a TSO only workaround
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
				 * if end byte alignment not correct move us
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
				 * into the next dword */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
				/* fall through */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
			case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
			case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
			case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
			case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
				pull_size = min((unsigned int)4, skb->data_len);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
				if (!__pskb_pull_tail(skb, pull_size)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
					DPRINTK(DRV, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
						"__pskb_pull_tail failed.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
					dev_kfree_skb_any(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
					return NETDEV_TX_OK;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
				}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
				len = skb->len - skb->data_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
			default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
				/* do nothing */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	/* reserve a descriptor for the offload context */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
		count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	/* Controller Erratum workaround */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
		count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	count += TXD_USE_COUNT(len, max_txd_pwr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	if (adapter->pcix_82544)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
		count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	/* work-around for errata 10 and it applies to all controllers
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	 * in PCI-X mode, so add one more descriptor to the count
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
			(len > 2015)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	nr_frags = skb_shinfo(skb)->nr_frags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	for (f = 0; f < nr_frags; f++)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
				       max_txd_pwr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	if (adapter->pcix_82544)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		count += nr_frags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	if (hw->tx_pkt_filtering &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	    (hw->mac_type == e1000_82573))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		e1000_transfer_dhcp_info(adapter, skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
		/* Collision - tell upper layer to requeue */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		return NETDEV_TX_LOCKED;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	/* need: count + 2 desc gap to keep tail from touching
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	 * head, otherwise try next time */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		return NETDEV_TX_BUSY;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	if (unlikely(hw->mac_type == e1000_82547)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
			netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
			return NETDEV_TX_BUSY;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		tx_flags |= E1000_TX_FLAGS_VLAN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	first = tx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	tso = e1000_tso(adapter, tx_ring, skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	if (tso < 0) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
		dev_kfree_skb_any(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		return NETDEV_TX_OK;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	if (likely(tso)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
		tx_ring->last_tx_tso = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
		tx_flags |= E1000_TX_FLAGS_TSO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		tx_flags |= E1000_TX_FLAGS_CSUM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	 * no longer assume, we must. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	if (likely(skb->protocol == htons(ETH_P_IP)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
		tx_flags |= E1000_TX_FLAGS_IPV4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	e1000_tx_queue(adapter, tx_ring, tx_flags,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	               e1000_tx_map(adapter, tx_ring, skb, first,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	                            max_per_txd, nr_frags, mss));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	netdev->trans_start = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	/* Make sure there is space in the ring for the next send. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	return NETDEV_TX_OK;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
 * e1000_tx_timeout - Respond to a Tx Hang
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
static void e1000_tx_timeout(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	/* Do the reset outside of interrupt context */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	adapter->tx_timeout_count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	schedule_work(&adapter->reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
static void e1000_reset_task(struct work_struct *work)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	struct e1000_adapter *adapter =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		container_of(work, struct e1000_adapter, reset_task);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	e1000_reinit_locked(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
 * e1000_get_stats - Get System Network Statistics
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
 * Returns the address of the device statistics structure.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
 * The statistics are actually updated from the timer callback.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	/* only return the current stats */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	return &adapter->net_stats;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
 * e1000_change_mtu - Change the Maximum Transfer Unit
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
 * @netdev: network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
 * @new_mtu: new value for maximum frame size
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
 * Returns 0 on success, negative on failure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	u16 eeprom_data = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
		return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	/* Adapter-specific max frame size limits. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	switch (hw->mac_type) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	case e1000_undefined ... e1000_82542_rev2_1:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	case e1000_ich8lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
			return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	case e1000_82573:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
		/* Jumbo Frames not supported if:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
		 * - this is not an 82573L device
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		 * - ASPM is enabled in any way (0x1A bits 3:2) */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
		e1000_read_eeprom(hw, EEPROM_INIT_3GIO_3, 1,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		                  &eeprom_data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
		if ((hw->device_id != E1000_DEV_ID_82573L) ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
				DPRINTK(PROBE, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
			            	"Jumbo Frames not supported.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
				return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
		/* ERT will be enabled later to enable wire speed receives */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
		/* fall through to get support */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	case e1000_82571:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	case e1000_82572:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	case e1000_80003es2lan:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
#define MAX_STD_JUMBO_FRAME_SIZE 9234
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
			return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	 * means we reserve 2 more, this pushes us to allocate from the next
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	 * larger slab size
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	if (max_frame <= E1000_RXBUFFER_256)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	else if (max_frame <= E1000_RXBUFFER_512)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	else if (max_frame <= E1000_RXBUFFER_1024)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	else if (max_frame <= E1000_RXBUFFER_2048)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	else if (max_frame <= E1000_RXBUFFER_4096)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	else if (max_frame <= E1000_RXBUFFER_8192)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	else if (max_frame <= E1000_RXBUFFER_16384)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	/* adjust allocation if LPE protects us, and we aren't using SBP */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	if (!hw->tbi_compatibility_on &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	netdev->mtu = new_mtu;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	hw->max_frame_size = max_frame;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	if (netif_running(netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
		e1000_reinit_locked(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
 * e1000_update_stats - Update the board statistics counters
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
void e1000_update_stats(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	unsigned long flags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	u16 phy_tmp;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	/*
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	 * Prevent stats update while adapter is being reset, or if the pci
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	 * connection is down.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	if (adapter->link_speed == 0)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	if (pci_channel_offline(pdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	spin_lock_irqsave(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	/* these counters are modified from e1000_tbi_adjust_stats,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	 * called from the interrupt context, so they must only
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	 * be written while holding adapter->stats_lock
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
	adapter->stats.crcerrs += er32(CRCERRS);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	adapter->stats.gprc += er32(GPRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	adapter->stats.gorcl += er32(GORCL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	adapter->stats.gorch += er32(GORCH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
	adapter->stats.bprc += er32(BPRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	adapter->stats.mprc += er32(MPRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	adapter->stats.roc += er32(ROC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	if (hw->mac_type != e1000_ich8lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		adapter->stats.prc64 += er32(PRC64);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		adapter->stats.prc127 += er32(PRC127);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		adapter->stats.prc255 += er32(PRC255);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		adapter->stats.prc511 += er32(PRC511);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		adapter->stats.prc1023 += er32(PRC1023);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		adapter->stats.prc1522 += er32(PRC1522);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	adapter->stats.symerrs += er32(SYMERRS);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	adapter->stats.mpc += er32(MPC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	adapter->stats.scc += er32(SCC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
	adapter->stats.ecol += er32(ECOL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	adapter->stats.mcc += er32(MCC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
	adapter->stats.latecol += er32(LATECOL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	adapter->stats.dc += er32(DC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	adapter->stats.sec += er32(SEC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	adapter->stats.rlec += er32(RLEC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	adapter->stats.xonrxc += er32(XONRXC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
	adapter->stats.xontxc += er32(XONTXC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	adapter->stats.xoffrxc += er32(XOFFRXC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	adapter->stats.xofftxc += er32(XOFFTXC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	adapter->stats.fcruc += er32(FCRUC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	adapter->stats.gptc += er32(GPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	adapter->stats.gotcl += er32(GOTCL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	adapter->stats.gotch += er32(GOTCH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	adapter->stats.rnbc += er32(RNBC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	adapter->stats.ruc += er32(RUC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	adapter->stats.rfc += er32(RFC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	adapter->stats.rjc += er32(RJC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	adapter->stats.torl += er32(TORL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	adapter->stats.torh += er32(TORH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	adapter->stats.totl += er32(TOTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	adapter->stats.toth += er32(TOTH);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	adapter->stats.tpr += er32(TPR);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	if (hw->mac_type != e1000_ich8lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		adapter->stats.ptc64 += er32(PTC64);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
		adapter->stats.ptc127 += er32(PTC127);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		adapter->stats.ptc255 += er32(PTC255);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		adapter->stats.ptc511 += er32(PTC511);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
		adapter->stats.ptc1023 += er32(PTC1023);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
		adapter->stats.ptc1522 += er32(PTC1522);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	adapter->stats.mptc += er32(MPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	adapter->stats.bptc += er32(BPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	/* used for adaptive IFS */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	hw->tx_packet_delta = er32(TPT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	adapter->stats.tpt += hw->tx_packet_delta;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	hw->collision_delta = er32(COLC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	adapter->stats.colc += hw->collision_delta;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	if (hw->mac_type >= e1000_82543) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
		adapter->stats.algnerrc += er32(ALGNERRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		adapter->stats.rxerrc += er32(RXERRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		adapter->stats.tncrs += er32(TNCRS);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		adapter->stats.cexterr += er32(CEXTERR);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		adapter->stats.tsctc += er32(TSCTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		adapter->stats.tsctfc += er32(TSCTFC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	if (hw->mac_type > e1000_82547_rev_2) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		adapter->stats.iac += er32(IAC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		adapter->stats.icrxoc += er32(ICRXOC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		if (hw->mac_type != e1000_ich8lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
			adapter->stats.icrxptc += er32(ICRXPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
			adapter->stats.icrxatc += er32(ICRXATC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
			adapter->stats.ictxptc += er32(ICTXPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
			adapter->stats.ictxatc += er32(ICTXATC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
			adapter->stats.ictxqec += er32(ICTXQEC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
			adapter->stats.ictxqmtc += er32(ICTXQMTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
			adapter->stats.icrxdmtc += er32(ICRXDMTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	/* Fill out the OS statistics structure */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	adapter->net_stats.multicast = adapter->stats.mprc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	adapter->net_stats.collisions = adapter->stats.colc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	/* Rx Errors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	/* RLEC on some newer hardware can be incorrect so build
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	* our own version based on RUC and ROC */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
		adapter->stats.crcerrs + adapter->stats.algnerrc +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
		adapter->stats.ruc + adapter->stats.roc +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
		adapter->stats.cexterr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	/* Tx Errors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	if (hw->bad_tx_carr_stats_fd &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	    adapter->link_duplex == FULL_DUPLEX) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		adapter->net_stats.tx_carrier_errors = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		adapter->stats.tncrs = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	/* Tx Dropped needs to be maintained elsewhere */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
	/* Phy Stats */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	if (hw->media_type == e1000_media_type_copper) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
		if ((adapter->link_speed == SPEED_1000) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
			adapter->phy_stats.idle_errors += phy_tmp;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
		if ((hw->mac_type <= e1000_82546) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		   (hw->phy_type == e1000_phy_m88) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
			adapter->phy_stats.receive_errors += phy_tmp;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	/* Management Stats */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	if (hw->has_smbus) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		adapter->stats.mgptc += er32(MGTPTC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		adapter->stats.mgprc += er32(MGTPRC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
		adapter->stats.mgpdc += er32(MGTPDC);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	spin_unlock_irqrestore(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
 * e1000_intr_msi - Interrupt Handler
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
 * @irq: interrupt number
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 * @data: pointer to a network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
static irqreturn_t e1000_intr_msi(int irq, void *data)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	struct net_device *netdev = data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	u32 icr = er32(ICR);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	/* in NAPI mode read ICR disables interrupts using IAM */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
		hw->get_link_status = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
		/* 80003ES2LAN workaround-- For packet buffer work-around on
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
		 * link down event; disable receives here in the ISR and reset
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
		 * adapter in watchdog */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
		if (netif_carrier_ok(netdev) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
		    (hw->mac_type == e1000_80003es2lan)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
			/* disable receives */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
			u32 rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		/* guard against interrupt when we're going down */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
	if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
		adapter->total_tx_bytes = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
		adapter->total_tx_packets = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
		adapter->total_rx_bytes = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
		adapter->total_rx_packets = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		__netif_rx_schedule(netdev, &adapter->napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	} else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	return IRQ_HANDLED;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
 * e1000_intr - Interrupt Handler
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
 * @irq: interrupt number
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
 * @data: pointer to a network interface device structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
static irqreturn_t e1000_intr(int irq, void *data)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	struct net_device *netdev = data;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	u32 rctl, icr = er32(ICR);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		return IRQ_NONE;  /* Not our interrupt */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	 * not set, then the adapter didn't send an interrupt */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
	if (unlikely(hw->mac_type >= e1000_82571 &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	             !(icr & E1000_ICR_INT_ASSERTED)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		return IRQ_NONE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	 * need for the IMC write */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		hw->get_link_status = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		/* 80003ES2LAN workaround--
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		 * For packet buffer work-around on link down event;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		 * disable receives here in the ISR and
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		 * reset adapter in watchdog
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		if (netif_carrier_ok(netdev) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		    (hw->mac_type == e1000_80003es2lan)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
			/* disable receives */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
			rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
		/* guard against interrupt when we're going down */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	if (unlikely(hw->mac_type < e1000_82571)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		/* disable interrupts, without the synchronize_irq bit */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		ew32(IMC, ~0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		E1000_WRITE_FLUSH();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	if (likely(netif_rx_schedule_prep(netdev, &adapter->napi))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
		adapter->total_tx_bytes = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		adapter->total_tx_packets = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		adapter->total_rx_bytes = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
		adapter->total_rx_packets = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
		__netif_rx_schedule(netdev, &adapter->napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	} else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
		/* this really should not happen! if it does it is basically a
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
		 * bug, but not a hard error, so enable ints and continue */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
		e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	return IRQ_HANDLED;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
 * e1000_clean - NAPI Rx polling callback
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
static int e1000_clean(struct napi_struct *napi, int budget)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	struct net_device *poll_dev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	int tx_cleaned = 0, work_done = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
	/* Must NOT use netdev_priv macro here. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	adapter = poll_dev->priv;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	/* e1000_clean is called per-cpu.  This lock protects
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	 * tx_ring[0] from being cleaned by multiple cpus
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	 * simultaneously.  A failure obtaining the lock means
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	 * tx_ring[0] is currently being cleaned anyway. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	if (spin_trylock(&adapter->tx_queue_lock)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		tx_cleaned = e1000_clean_tx_irq(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
						&adapter->tx_ring[0]);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		spin_unlock(&adapter->tx_queue_lock);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
	                  &work_done, budget);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	if (tx_cleaned)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		work_done = budget;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	/* If budget not fully consumed, exit the polling mode */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	if (work_done < budget) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		if (likely(adapter->itr_setting & 3))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
			e1000_set_itr(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		netif_rx_complete(poll_dev, napi);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	return work_done;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
			       struct e1000_tx_ring *tx_ring)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	struct e1000_tx_desc *tx_desc, *eop_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	unsigned int i, eop;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	unsigned int count = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	bool cleaned = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	unsigned int total_tx_bytes=0, total_tx_packets=0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	i = tx_ring->next_to_clean;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	eop = tx_ring->buffer_info[i].next_to_watch;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
		for (cleaned = false; !cleaned; ) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
			tx_desc = E1000_TX_DESC(*tx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
			buffer_info = &tx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
			cleaned = (i == eop);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
			if (cleaned) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
				struct sk_buff *skb = buffer_info->skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
				unsigned int segs, bytecount;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
				segs = skb_shinfo(skb)->gso_segs ?: 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
				/* multiply data chunks by size of headers */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
				bytecount = ((segs - 1) * skb_headlen(skb)) +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
				            skb->len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
				total_tx_packets += segs;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
				total_tx_bytes += bytecount;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
			tx_desc->upper.data = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
			if (unlikely(++i == tx_ring->count)) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		eop = tx_ring->buffer_info[i].next_to_watch;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
#define E1000_TX_WEIGHT 64
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		/* weight of a sort for tx, to avoid endless transmit cleanup */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		if (count++ == E1000_TX_WEIGHT)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	tx_ring->next_to_clean = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
#define TX_WAKE_THRESHOLD 32
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	if (unlikely(cleaned && netif_carrier_ok(netdev) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
		/* Make sure that anybody stopping the queue after this
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		 * sees the new next_to_clean.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
		smp_mb();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
		if (netif_queue_stopped(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
			netif_wake_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
			++adapter->restart_queue;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	if (adapter->detect_tx_hung) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		/* Detect a transmit hang in hardware, this serializes the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		 * check with the clearing of time_stamp and movement of i */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		adapter->detect_tx_hung = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
		if (tx_ring->buffer_info[eop].dma &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		               (adapter->tx_timeout_factor * HZ))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
			/* detected Tx unit hang */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
					"  Tx Queue             <%lu>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
					"  TDH                  <%x>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
					"  TDT                  <%x>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
					"  next_to_use          <%x>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
					"  next_to_clean        <%x>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
					"buffer_info[next_to_clean]\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
					"  time_stamp           <%lx>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
					"  next_to_watch        <%x>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
					"  jiffies              <%lx>\n"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
					"  next_to_watch.status <%x>\n",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
				(unsigned long)((tx_ring - adapter->tx_ring) /
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
					sizeof(struct e1000_tx_ring)),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
				readl(hw->hw_addr + tx_ring->tdh),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
				readl(hw->hw_addr + tx_ring->tdt),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
				tx_ring->next_to_use,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
				tx_ring->next_to_clean,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
				tx_ring->buffer_info[eop].time_stamp,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
				eop,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
				jiffies,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
				eop_desc->upper.fields.status);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
			netif_stop_queue(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	adapter->total_tx_bytes += total_tx_bytes;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	adapter->total_tx_packets += total_tx_packets;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	adapter->net_stats.tx_bytes += total_tx_bytes;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	adapter->net_stats.tx_packets += total_tx_packets;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	return cleaned;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
 * e1000_rx_checksum - Receive Checksum Offload for 82543
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
 * @adapter:     board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
 * @status_err:  receive descriptor status and error fields
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
 * @csum:        receive descriptor csum field
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
 * @sk_buff:     socket buffer with received data
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
			      u32 csum, struct sk_buff *skb)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	u16 status = (u16)status_err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	u8 errors = (u8)(status_err >> 24);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	skb->ip_summed = CHECKSUM_NONE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	/* 82543 or newer only */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	if (unlikely(hw->mac_type < e1000_82543)) return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	/* Ignore Checksum bit is set */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	/* TCP/UDP checksum error bit is set */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		/* let the stack verify checksum errors */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
		adapter->hw_csum_err++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
	/* TCP/UDP Checksum has not been calculated */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	if (hw->mac_type <= e1000_82547_rev_2) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		if (!(status & E1000_RXD_STAT_TCPCS))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	/* It must be a TCP or UDP packet with a valid checksum */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		/* TCP checksum is good */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		skb->ip_summed = CHECKSUM_UNNECESSARY;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	} else if (hw->mac_type > e1000_82547_rev_2) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		/* IP fragment with UDP payload */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
		/* Hardware complements the payload checksum, so we undo it
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
		 * and then put the value in host order for further stack use.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		__sum16 sum = (__force __sum16)htons(csum);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		skb->csum = csum_unfold(~sum);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
		skb->ip_summed = CHECKSUM_COMPLETE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	adapter->hw_csum_good++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
 * @adapter: board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			       struct e1000_rx_ring *rx_ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			       int *work_done, int work_to_do)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	struct e1000_rx_desc *rx_desc, *next_rxd;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	struct e1000_buffer *buffer_info, *next_buffer;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	unsigned long flags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	u32 length;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	u8 last_byte;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	int cleaned_count = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	bool cleaned = false;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
	unsigned int total_rx_bytes=0, total_rx_packets=0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
	i = rx_ring->next_to_clean;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	rx_desc = E1000_RX_DESC(*rx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	buffer_info = &rx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	while (rx_desc->status & E1000_RXD_STAT_DD) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		struct sk_buff *skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
		u8 status;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
		if (*work_done >= work_to_do)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		(*work_done)++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		status = rx_desc->status;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		skb = buffer_info->skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
		buffer_info->skb = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		prefetch(skb->data - NET_IP_ALIGN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		if (++i == rx_ring->count) i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		next_rxd = E1000_RX_DESC(*rx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
		prefetch(next_rxd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		next_buffer = &rx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		cleaned = true;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
		cleaned_count++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
		pci_unmap_single(pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
		                 buffer_info->dma,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		                 buffer_info->length,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
		                 PCI_DMA_FROMDEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		length = le16_to_cpu(rx_desc->length);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
			/* All receives must fit into a single buffer */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
			E1000_DBG("%s: Receive packet consumed multiple"
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
				  " buffers\n", netdev->name);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			/* recycle */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
			buffer_info->skb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
			goto next_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
			last_byte = *(skb->data + length - 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
				       last_byte)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
				spin_lock_irqsave(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
				e1000_tbi_adjust_stats(hw, &adapter->stats,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
				                       length, skb->data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
				spin_unlock_irqrestore(&adapter->stats_lock,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
				                       flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
				length--;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
				/* recycle */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
				buffer_info->skb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
				goto next_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
		/* adjust length to remove Ethernet CRC, this must be
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		 * done after the TBI_ACCEPT workaround above */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
		length -= 4;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		/* probably a little skewed due to removing CRC */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
		total_rx_bytes += length;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		total_rx_packets++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		/* code added for copybreak, this should improve
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		 * performance for small packets with large amounts
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
		 * of reassembly being done in the stack */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		if (length < copybreak) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
			struct sk_buff *new_skb =
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
			if (new_skb) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
				skb_reserve(new_skb, NET_IP_ALIGN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
				skb_copy_to_linear_data_offset(new_skb,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
							       -NET_IP_ALIGN,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
							       (skb->data -
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
							        NET_IP_ALIGN),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
							       (length +
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
							        NET_IP_ALIGN));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
				/* save the skb in buffer_info as good */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
				buffer_info->skb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
				skb = new_skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
			/* else just continue with the old one */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
		/* end copybreak code */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
		skb_put(skb, length);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
		/* Receive Checksum Offload */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
		e1000_rx_checksum(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
				  (u32)(status) |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
				  ((u32)(rx_desc->errors) << 24),
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
				  le16_to_cpu(rx_desc->csum), skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		skb->protocol = eth_type_trans(skb, netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		if (unlikely(adapter->vlgrp &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			    (status & E1000_RXD_STAT_VP))) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
						 le16_to_cpu(rx_desc->special));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
			netif_receive_skb(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		netdev->last_rx = jiffies;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
next_desc:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		rx_desc->status = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		/* return some buffers to hardware, one at a time is too slow */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
			cleaned_count = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
		/* use prefetched values */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
		rx_desc = next_rxd;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		buffer_info = next_buffer;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	rx_ring->next_to_clean = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
	if (cleaned_count)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
	adapter->total_rx_packets += total_rx_packets;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	adapter->total_rx_bytes += total_rx_bytes;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	adapter->net_stats.rx_bytes += total_rx_bytes;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	adapter->net_stats.rx_packets += total_rx_packets;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	return cleaned;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
 * @adapter: address of board private structure
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
				   struct e1000_rx_ring *rx_ring,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
				   int cleaned_count)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	struct net_device *netdev = adapter->netdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
	struct pci_dev *pdev = adapter->pdev;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	struct e1000_rx_desc *rx_desc;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	struct e1000_buffer *buffer_info;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	struct sk_buff *skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	unsigned int i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	i = rx_ring->next_to_use;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	buffer_info = &rx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	while (cleaned_count--) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
		skb = buffer_info->skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		if (skb) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			skb_trim(skb, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
			goto map_skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
		skb = netdev_alloc_skb(netdev, bufsz);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		if (unlikely(!skb)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			/* Better luck next round */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
			adapter->alloc_rx_buff_failed++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
			break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
		/* Fix for errata 23, can't cross 64kB boundary */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			struct sk_buff *oldskb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
					     "at %p\n", bufsz, skb->data);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
			/* Try again, without freeing the previous */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
			skb = netdev_alloc_skb(netdev, bufsz);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
			/* Failed allocation, critical failure */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			if (!skb) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
				dev_kfree_skb(oldskb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
				/* give up */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
				dev_kfree_skb(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
				dev_kfree_skb(oldskb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
				break; /* while !buffer_info->skb */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			/* Use new allocation */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
			dev_kfree_skb(oldskb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
		/* Make buffer alignment 2 beyond a 16 byte boundary
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		 * this will result in a 16 byte aligned IP header after
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		 * the 14 byte MAC header is removed
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		skb_reserve(skb, NET_IP_ALIGN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		buffer_info->skb = skb;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		buffer_info->length = adapter->rx_buffer_len;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
map_skb:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
		buffer_info->dma = pci_map_single(pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
						  skb->data,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
						  adapter->rx_buffer_len,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
						  PCI_DMA_FROMDEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		/* Fix for errata 23, can't cross 64kB boundary */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
		if (!e1000_check_64k_bound(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
					(void *)(unsigned long)buffer_info->dma,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
					adapter->rx_buffer_len)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
			DPRINTK(RX_ERR, ERR,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
				"dma align check failed: %u bytes at %p\n",
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
				adapter->rx_buffer_len,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
				(void *)(unsigned long)buffer_info->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
			dev_kfree_skb(skb);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
			buffer_info->skb = NULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
			pci_unmap_single(pdev, buffer_info->dma,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
					 adapter->rx_buffer_len,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
					 PCI_DMA_FROMDEVICE);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
			break; /* while !buffer_info->skb */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		rx_desc = E1000_RX_DESC(*rx_ring, i);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
		if (unlikely(++i == rx_ring->count))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
			i = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		buffer_info = &rx_ring->buffer_info[i];
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	if (likely(rx_ring->next_to_use != i)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
		rx_ring->next_to_use = i;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
		if (unlikely(i-- == 0))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
			i = (rx_ring->count - 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		/* Force memory writes to complete before letting h/w
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
		 * know there are new descriptors to fetch.  (Only
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
		 * applicable for weak-ordered memory model archs,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
		 * such as IA-64). */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		wmb();
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		writel(i, hw->hw_addr + rx_ring->rdt);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
 * @adapter:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
static void e1000_smartspeed(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	u16 phy_status;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	u16 phy_ctrl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	if (adapter->smartspeed == 0) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		/* If Master/Slave config fault is asserted twice,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		 * we assume back-to-back */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
					    phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
			adapter->smartspeed++;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
			if (!e1000_phy_setup_autoneg(hw) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
			   !e1000_read_phy_reg(hw, PHY_CTRL,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
				   	       &phy_ctrl)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
					     MII_CR_RESTART_AUTO_NEG);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
				e1000_write_phy_reg(hw, PHY_CTRL,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
						    phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		/* If still no link, perhaps using 2/3 pair cable */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		phy_ctrl |= CR_1000T_MS_ENABLE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		if (!e1000_phy_setup_autoneg(hw) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
				     MII_CR_RESTART_AUTO_NEG);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		adapter->smartspeed = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
 * e1000_ioctl -
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
 * @netdev:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
 * @ifreq:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
 * @cmd:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	switch (cmd) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	case SIOCGMIIPHY:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	case SIOCGMIIREG:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	case SIOCSMIIREG:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		return e1000_mii_ioctl(netdev, ifr, cmd);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		return -EOPNOTSUPP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
 * e1000_mii_ioctl -
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
 * @netdev:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
 * @ifreq:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
 * @cmd:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
 **/
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
			   int cmd)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	struct mii_ioctl_data *data = if_mii(ifr);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	int retval;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	u16 mii_reg;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	u16 spddplx;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	unsigned long flags;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	if (hw->media_type != e1000_media_type_copper)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		return -EOPNOTSUPP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	switch (cmd) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	case SIOCGMIIPHY:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		data->phy_id = hw->phy_addr;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	case SIOCGMIIREG:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		if (!capable(CAP_NET_ADMIN))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
			return -EPERM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
		spin_lock_irqsave(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
				   &data->val_out)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
			return -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	case SIOCSMIIREG:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
		if (!capable(CAP_NET_ADMIN))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
			return -EPERM;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		if (data->reg_num & ~(0x1F))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
			return -EFAULT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		mii_reg = data->val_in;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
		spin_lock_irqsave(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
		if (e1000_write_phy_reg(hw, data->reg_num,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
					mii_reg)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
			return -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
		if (hw->media_type == e1000_media_type_copper) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
			switch (data->reg_num) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
			case PHY_CTRL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
				if (mii_reg & MII_CR_POWER_DOWN)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
					hw->autoneg = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
					hw->autoneg_advertised = 0x2F;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
				} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
					if (mii_reg & 0x40)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
						spddplx = SPEED_1000;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
					else if (mii_reg & 0x2000)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
						spddplx = SPEED_100;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
					else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
						spddplx = SPEED_10;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
					spddplx += (mii_reg & 0x100)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
						   ? DUPLEX_FULL :
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
						   DUPLEX_HALF;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
					retval = e1000_set_spd_dplx(adapter,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
								    spddplx);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
					if (retval)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
						return retval;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
				}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
				if (netif_running(adapter->netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
					e1000_reinit_locked(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
				else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
					e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
			case M88E1000_PHY_SPEC_CTRL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
			case M88E1000_EXT_PHY_SPEC_CTRL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
				if (e1000_phy_reset(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
					return -EIO;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
			switch (data->reg_num) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
			case PHY_CTRL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
				if (mii_reg & MII_CR_POWER_DOWN)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
					break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
				if (netif_running(adapter->netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
					e1000_reinit_locked(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
				else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
					e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
				break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		return -EOPNOTSUPP;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	return E1000_SUCCESS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
void e1000_pci_set_mwi(struct e1000_hw *hw)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	struct e1000_adapter *adapter = hw->back;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	int ret_val = pci_set_mwi(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	if (ret_val)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
void e1000_pci_clear_mwi(struct e1000_hw *hw)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	struct e1000_adapter *adapter = hw->back;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	pci_clear_mwi(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	struct e1000_adapter *adapter = hw->back;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	return pcix_get_mmrbc(adapter->pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	struct e1000_adapter *adapter = hw->back;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	pcix_set_mmrbc(adapter->pdev, mmrbc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
    struct e1000_adapter *adapter = hw->back;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
    u16 cap_offset;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
    if (!cap_offset)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
        return -E1000_ERR_CONFIG;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
    return E1000_SUCCESS;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	outl(value, port);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
static void e1000_vlan_rx_register(struct net_device *netdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
				   struct vlan_group *grp)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	u32 ctrl, rctl;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		e1000_irq_disable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
	adapter->vlgrp = grp;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	if (grp) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		/* enable VLAN tag insert/strip */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		ctrl = er32(CTRL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		ctrl |= E1000_CTRL_VME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		ew32(CTRL, ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		if (adapter->hw.mac_type != e1000_ich8lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
			/* enable VLAN receive filtering */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
			rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
			rctl &= ~E1000_RCTL_CFIEN;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
			ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
			e1000_update_mng_vlan(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		/* disable VLAN tag insert/strip */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		ctrl = er32(CTRL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		ctrl &= ~E1000_CTRL_VME;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
		ew32(CTRL, ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		if (adapter->hw.mac_type != e1000_ich8lan) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
			if (adapter->mng_vlan_id !=
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			    (u16)E1000_MNG_VLAN_NONE) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
				e1000_vlan_rx_kill_vid(netdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
				                       adapter->mng_vlan_id);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
			}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	u32 vfta, index;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	if ((hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	    (vid == adapter->mng_vlan_id))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	/* add VID to filter table */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	index = (vid >> 5) & 0x7F;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	vfta |= (1 << (vid & 0x1F));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	e1000_write_vfta(hw, index, vfta);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	u32 vfta, index;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		e1000_irq_disable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	if (!test_bit(__E1000_DOWN, &adapter->flags))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
		e1000_irq_enable(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	if ((hw->mng_cookie.status &
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	    (vid == adapter->mng_vlan_id)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
		/* release control to f/w */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
		e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	/* remove VID from filter table */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	index = (vid >> 5) & 0x7F;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	vfta &= ~(1 << (vid & 0x1F));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	e1000_write_vfta(hw, index, vfta);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
static void e1000_restore_vlan(struct e1000_adapter *adapter)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	if (adapter->vlgrp) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
		u16 vid;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
			if (!vlan_group_get_device(adapter->vlgrp, vid))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
				continue;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	hw->autoneg = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	/* Fiber NICs only allow 1000 gbps Full duplex */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	if ((hw->media_type == e1000_media_type_fiber) &&
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
		return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	switch (spddplx) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	case SPEED_10 + DUPLEX_HALF:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
		hw->forced_speed_duplex = e1000_10_half;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	case SPEED_10 + DUPLEX_FULL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		hw->forced_speed_duplex = e1000_10_full;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	case SPEED_100 + DUPLEX_HALF:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		hw->forced_speed_duplex = e1000_100_half;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	case SPEED_100 + DUPLEX_FULL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		hw->forced_speed_duplex = e1000_100_full;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	case SPEED_1000 + DUPLEX_FULL:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		hw->autoneg = 1;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		break;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	default:
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
		return -EINVAL;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	u32 ctrl, ctrl_ext, rctl, status;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	u32 wufc = adapter->wol;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
#ifdef CONFIG_PM
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	int retval = 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	netif_device_detach(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	if (netif_running(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
		e1000_down(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
#ifdef CONFIG_PM
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	retval = pci_save_state(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	if (retval)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		return retval;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	status = er32(STATUS);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	if (status & E1000_STATUS_LU)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		wufc &= ~E1000_WUFC_LNKC;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	if (wufc) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		e1000_setup_rctl(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		e1000_set_rx_mode(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		/* turn on all-multi mode if wake on multicast is enabled */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		if (wufc & E1000_WUFC_MC) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
			rctl = er32(RCTL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
			rctl |= E1000_RCTL_MPE;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
			ew32(RCTL, rctl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		if (hw->mac_type >= e1000_82540) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
			ctrl = er32(CTRL);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
			/* advertise wake from D3Cold */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
			#define E1000_CTRL_ADVD3WUC 0x00100000
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
			/* phy power management enable */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
			ctrl |= E1000_CTRL_ADVD3WUC |
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
				E1000_CTRL_EN_PHY_PWR_MGMT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
			ew32(CTRL, ctrl);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
		if (hw->media_type == e1000_media_type_fiber ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
		   hw->media_type == e1000_media_type_internal_serdes) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
			/* keep the laser running in D3 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
			ctrl_ext = er32(CTRL_EXT);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			ew32(CTRL_EXT, ctrl_ext);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		/* Allow time for pending master requests to run */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
		e1000_disable_pciex_master(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		ew32(WUC, E1000_WUC_PME_EN);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		ew32(WUFC, wufc);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		pci_enable_wake(pdev, PCI_D3hot, 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		pci_enable_wake(pdev, PCI_D3cold, 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	} else {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		ew32(WUC, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		ew32(WUFC, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		pci_enable_wake(pdev, PCI_D3hot, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		pci_enable_wake(pdev, PCI_D3cold, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	e1000_release_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	/* make sure adapter isn't asleep if manageability is enabled */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	if (adapter->en_mng_pt) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		pci_enable_wake(pdev, PCI_D3hot, 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		pci_enable_wake(pdev, PCI_D3cold, 1);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	if (hw->phy_type == e1000_phy_igp_3)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
		e1000_phy_powerdown_workaround(hw);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	if (netif_running(netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		e1000_free_irq(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	 * would have already happened in close and is redundant. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	e1000_release_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	pci_disable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
#ifdef CONFIG_PM
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
static int e1000_resume(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	u32 err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	pci_set_power_state(pdev, PCI_D0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	pci_restore_state(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	if (adapter->need_ioport)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		err = pci_enable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		err = pci_enable_device_mem(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	pci_set_master(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	pci_enable_wake(pdev, PCI_D3hot, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	pci_enable_wake(pdev, PCI_D3cold, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	if (netif_running(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		err = e1000_request_irq(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
		if (err)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
			return err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	e1000_power_up_phy(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	ew32(WUS, ~0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	e1000_init_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	if (netif_running(netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
		e1000_up(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	netif_device_attach(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	/* If the controller is 82573 and f/w is AMT, do not set
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	 * DRV_LOAD until the interface is up.  For all other cases,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	 * let the f/w know that the h/w is now under the control
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	 * of the driver. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	if (hw->mac_type != e1000_82573 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	    !e1000_check_mng_mode(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		e1000_get_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	return 0;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
static void e1000_shutdown(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	e1000_suspend(pdev, PMSG_SUSPEND);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
#ifdef CONFIG_NET_POLL_CONTROLLER
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
/*
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
 * Polling 'interrupt' - used by things like netconsole to send skbs
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
 * without having to re-enable interrupts. It's not called while
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
 * the interrupt routine is executing.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
static void e1000_netpoll(struct net_device *netdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	struct e1000_adapter *adapter = netdev_priv(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	disable_irq(adapter->pdev->irq);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	e1000_intr(adapter->pdev->irq, netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	enable_irq(adapter->pdev->irq);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
#endif
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
 * e1000_io_error_detected - called when PCI error is detected
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
 * @pdev: Pointer to PCI device
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
 * @state: The current pci conneection state
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
 * This function is called after a PCI bus error affecting
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
 * this device has been detected.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
						pci_channel_state_t state)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	struct e1000_adapter *adapter = netdev->priv;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	netif_device_detach(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	if (netif_running(netdev))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
		e1000_down(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	pci_disable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	/* Request a slot slot reset. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	return PCI_ERS_RESULT_NEED_RESET;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
 * e1000_io_slot_reset - called after the pci bus has been reset.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
 * @pdev: Pointer to PCI device
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
 * Restart the card from scratch, as if from a cold-boot. Implementation
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
 * resembles the first-half of the e1000_resume routine.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
	struct e1000_adapter *adapter = netdev->priv;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
	int err;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	if (adapter->need_ioport)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
		err = pci_enable_device(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	else
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
		err = pci_enable_device_mem(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	if (err) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		return PCI_ERS_RESULT_DISCONNECT;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	pci_set_master(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	pci_enable_wake(pdev, PCI_D3hot, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	pci_enable_wake(pdev, PCI_D3cold, 0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
	e1000_reset(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
	ew32(WUS, ~0);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	return PCI_ERS_RESULT_RECOVERED;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
/**
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
 * e1000_io_resume - called when traffic can start flowing again.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
 * @pdev: Pointer to PCI device
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
 *
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
 * This callback is called when the error recovery driver tells us that
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
 * its OK to resume normal operation. Implementation resembles the
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
 * second-half of the e1000_resume routine.
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
 */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
static void e1000_io_resume(struct pci_dev *pdev)
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
{
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
	struct net_device *netdev = pci_get_drvdata(pdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	struct e1000_adapter *adapter = netdev->priv;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	struct e1000_hw *hw = &adapter->hw;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	e1000_init_manageability(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	if (netif_running(netdev)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		if (e1000_up(adapter)) {
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
			printk("e1000: can't bring device back up after reset\n");
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
			return;
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
	}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
	netif_device_attach(netdev);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
	/* If the controller is 82573 and f/w is AMT, do not set
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
	 * DRV_LOAD until the interface is up.  For all other cases,
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
	 * let the f/w know that the h/w is now under the control
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	 * of the driver. */
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	if (hw->mac_type != e1000_82573 ||
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
	    !e1000_check_mng_mode(hw))
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		e1000_get_hw_control(adapter);
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
}
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
3a066ec73fb2 Added e1000 driver for 2.6.28.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
/* e1000_main.c */