devices/e1000/e1000_main-2.6.20-ethercat.c
author Dominik Staubli <ch1010252@ch10pc423>
Thu, 21 Jan 2010 11:09:31 +0100
changeset 1798 e7733f825982
parent 1325 16aacb421bd4
child 2050 a3e59f2a8589
permissions -rw-r--r--
Domain datagram working counter calculation bugfix: increment expected wc for a given slave & direction just once for each datagram
This bug occurs if you configure more than one SM in the same direction on the same slave
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
    26
  
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
    27
  vim: noexpandtab
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000-2.6.20-ethercat.h"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <net/ip6_checksum.h>
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
char e1000_driver_name[] = "ec_e1000";
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
static char e1000_driver_string[] = "EtherCAT Intel(R) PRO/1000 Network Driver";
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#ifndef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#define DRIVERNAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#define DRIVERNAPI "-NAPI"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#define DRV_VERSION "7.3.15-k2"DRIVERNAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
char e1000_driver_version[] = DRV_VERSION;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
/* e1000_pci_tbl - PCI Device ID Table
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 * Last entry must be all 0s
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 * Macro expands to...
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
static struct pci_device_id e1000_pci_tbl[] = {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x1049),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x104A),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x104B),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x104C),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x104D),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x105E),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x105F),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x1060),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	INTEL_E1000_ETHERNET_DEVICE(0x107D),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	INTEL_E1000_ETHERNET_DEVICE(0x107E),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	INTEL_E1000_ETHERNET_DEVICE(0x107F),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	INTEL_E1000_ETHERNET_DEVICE(0x108B),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	INTEL_E1000_ETHERNET_DEVICE(0x108C),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	INTEL_E1000_ETHERNET_DEVICE(0x1096),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	INTEL_E1000_ETHERNET_DEVICE(0x1098),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	INTEL_E1000_ETHERNET_DEVICE(0x109A),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	INTEL_E1000_ETHERNET_DEVICE(0x10A4),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	INTEL_E1000_ETHERNET_DEVICE(0x10B9),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	INTEL_E1000_ETHERNET_DEVICE(0x10BA),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	INTEL_E1000_ETHERNET_DEVICE(0x10BB),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	INTEL_E1000_ETHERNET_DEVICE(0x10BC),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	INTEL_E1000_ETHERNET_DEVICE(0x10C4),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	INTEL_E1000_ETHERNET_DEVICE(0x10C5),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	/* required last entry */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{0,}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
};
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
// do not auto-load driver
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
int e1000_up(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
void e1000_down(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
void e1000_reinit_locked(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
void e1000_reset(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
                             struct e1000_tx_ring *txdr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
                             struct e1000_rx_ring *rxdr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
                             struct e1000_tx_ring *tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
                             struct e1000_rx_ring *rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
void e1000_update_stats(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static int e1000_init_module(void);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
static void e1000_exit_module(void);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static void __devexit e1000_remove(struct pci_dev *pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static int e1000_alloc_queues(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
static int e1000_sw_init(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_open(struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
static int e1000_close(struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
static void e1000_configure_tx(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
static void e1000_configure_rx(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static void e1000_setup_rctl(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
                                struct e1000_tx_ring *tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
                                struct e1000_rx_ring *rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
static void e1000_set_multi(struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
static void e1000_update_phy_info(unsigned long data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static void e1000_watchdog(unsigned long data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static void e1000_82547_tx_fifo_stall(unsigned long data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static int e1000_set_mac(struct net_device *netdev, void *p);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
void ec_poll(struct net_device *);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static irqreturn_t e1000_intr(int irq, void *data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
#ifdef CONFIG_PCI_MSI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
static irqreturn_t e1000_intr_msi(int irq, void *data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
                                    struct e1000_tx_ring *tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static int e1000_clean(struct net_device *poll_dev, int *budget);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
                                    struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
                                    int *work_done, int work_to_do);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
                                       struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
                                       int *work_done, int work_to_do);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
#else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
                                    struct e1000_rx_ring *rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
                                       struct e1000_rx_ring *rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
                                   struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
				   int cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
                                      struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
				      int cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
			   int cmd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
void e1000_set_ethtool_ops(struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
static void e1000_tx_timeout(struct net_device *dev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
static void e1000_reset_task(struct work_struct *work);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
static void e1000_smartspeed(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
                                       struct sk_buff *skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
static void e1000_restore_vlan(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
static int e1000_resume(struct pci_dev *pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
static void e1000_shutdown(struct pci_dev *pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
#ifdef CONFIG_NET_POLL_CONTROLLER
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
/* for netdump / net console */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
static void e1000_netpoll (struct net_device *netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
extern void e1000_check_options(struct e1000_adapter *adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
#define COPYBREAK_DEFAULT 256
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
module_param(copybreak, uint, 0644);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
MODULE_PARM_DESC(copybreak,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	"Maximum size of packet that is copied to a new buffer on receive");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
                     pci_channel_state_t state);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
static void e1000_io_resume(struct pci_dev *pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
static struct pci_error_handlers e1000_err_handler = {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	.error_detected = e1000_io_error_detected,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	.slot_reset = e1000_io_slot_reset,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	.resume = e1000_io_resume,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
};
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
static struct pci_driver e1000_driver = {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	.name     = e1000_driver_name,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	.id_table = e1000_pci_tbl,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	.probe    = e1000_probe,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	.remove   = __devexit_p(e1000_remove),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	/* Power Managment Hooks */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	.suspend  = e1000_suspend,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	.resume   = e1000_resume,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	.shutdown = e1000_shutdown,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	.err_handler = &e1000_err_handler
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
};
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
MODULE_LICENSE("GPL");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
MODULE_VERSION(DRV_VERSION);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
module_param(debug, int, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
 * e1000_init_module - Driver Registration Routine
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
 * e1000_init_module is the first routine called when the driver is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
 * loaded. All it does is register with the PCI subsystem.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
static int __init
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
e1000_init_module(void)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	int ret;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	printk(KERN_INFO "%s - version %s\n",
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	       e1000_driver_string, e1000_driver_version);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	printk(KERN_INFO "%s\n", e1000_copyright);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	ret = pci_register_driver(&e1000_driver);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	if (copybreak != COPYBREAK_DEFAULT) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		if (copybreak == 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
			printk(KERN_INFO "e1000: copybreak disabled\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
			printk(KERN_INFO "e1000: copybreak enabled for "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
			       "packets <= %u bytes\n", copybreak);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	return ret;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
module_init(e1000_init_module);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
 * e1000_exit_module - Driver Exit Cleanup Routine
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
 * e1000_exit_module is called just before the driver is removed
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
 * from memory.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
static void __exit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
e1000_exit_module(void)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	pci_unregister_driver(&e1000_driver);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
module_exit(e1000_exit_module);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
static int e1000_request_irq(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	int flags, err = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
		return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	flags = IRQF_SHARED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
#ifdef CONFIG_PCI_MSI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	if (adapter->hw.mac_type >= e1000_82571) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		adapter->have_msi = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		if ((err = pci_enable_msi(adapter->pdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
			 "Unable to allocate MSI interrupt Error: %d\n", err);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
			adapter->have_msi = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	if (adapter->have_msi) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		flags &= ~IRQF_SHARED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		err = request_irq(adapter->pdev->irq, &e1000_intr_msi, flags,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		                  netdev->name, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		if (err)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
			       "Unable to allocate interrupt Error: %d\n", err);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	} else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	if ((err = request_irq(adapter->pdev->irq, &e1000_intr, flags,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	                       netdev->name, netdev)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		        "Unable to allocate interrupt Error: %d\n", err);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
static void e1000_free_irq(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	free_irq(adapter->pdev->irq, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
#ifdef CONFIG_PCI_MSI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	if (adapter->have_msi)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		pci_disable_msi(adapter->pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
 * e1000_irq_disable - Mask off interrupt generation on the NIC
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
e1000_irq_disable(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
    if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
        return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
	atomic_inc(&adapter->irq_sem);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
	E1000_WRITE_REG(&adapter->hw, IMC, ~0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	E1000_WRITE_FLUSH(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	synchronize_irq(adapter->pdev->irq);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
 * e1000_irq_enable - Enable default interrupt generation settings
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
e1000_irq_enable(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
    if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
        return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		E1000_WRITE_FLUSH(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
e1000_update_mng_vlan(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	uint16_t vid = adapter->hw.mng_cookie.vlan_id;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	uint16_t old_vid = adapter->mng_vlan_id;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	if (adapter->vlgrp) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		if (!adapter->vlgrp->vlan_devices[vid]) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
			if (adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
				e1000_vlan_rx_add_vid(netdev, vid);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
				adapter->mng_vlan_id = vid;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
			} else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
			if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
					(vid != old_vid) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
					!adapter->vlgrp->vlan_devices[old_vid])
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
				e1000_vlan_rx_kill_vid(netdev, old_vid);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		} else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
			adapter->mng_vlan_id = vid;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 * e1000_release_hw_control - release control of the h/w to f/w
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
 * For ASF and Pass Through versions of f/w this means that the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
 * driver is no longer loaded. For AMT version (only with 82573) i
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
 * of the f/w this means that the network i/f is closed.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
e1000_release_hw_control(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	uint32_t ctrl_ext;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
	uint32_t swsm;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	uint32_t extcnf;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	/* Let firmware taken over control of h/w */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		swsm = E1000_READ_REG(&adapter->hw, SWSM);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
		E1000_WRITE_REG(&adapter->hw, SWSM,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
				swsm & ~E1000_SWSM_DRV_LOAD);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
		extcnf = E1000_READ_REG(&adapter->hw, CTRL_EXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
				extcnf & ~E1000_CTRL_EXT_DRV_LOAD);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
 * e1000_get_hw_control - get control of the h/w from f/w
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
 * For ASF and Pass Through versions of f/w this means that
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
 * the driver is loaded. For AMT version (only with 82573)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 * of the f/w this means that the network i/f is open.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
e1000_get_hw_control(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	uint32_t ctrl_ext;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	uint32_t swsm;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	uint32_t extcnf;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	/* Let firmware know the driver has taken over */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
	case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		swsm = E1000_READ_REG(&adapter->hw, SWSM);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		E1000_WRITE_REG(&adapter->hw, SWSM,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
				swsm | E1000_SWSM_DRV_LOAD);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
		extcnf = E1000_READ_REG(&adapter->hw, EXTCNF_CTRL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		E1000_WRITE_REG(&adapter->hw, EXTCNF_CTRL,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
				extcnf | E1000_EXTCNF_CTRL_SWFLAG);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
e1000_init_manageability(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	if (adapter->en_mng_pt) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		uint32_t manc = E1000_READ_REG(&adapter->hw, MANC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		/* disable hardware interception of ARP */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		manc &= ~(E1000_MANC_ARP_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		/* enable receiving management packets to the host */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		/* this will probably generate destination unreachable messages
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		 * from the host OS, but the packets will be handled on SMBUS */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
		if (adapter->hw.has_manc2h) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
			uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
			manc |= E1000_MANC_EN_MNG2HOST;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
#define E1000_MNG2HOST_PORT_623 (1 << 5)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
#define E1000_MNG2HOST_PORT_664 (1 << 6)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
			manc2h |= E1000_MNG2HOST_PORT_623;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
			manc2h |= E1000_MNG2HOST_PORT_664;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
			E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		E1000_WRITE_REG(&adapter->hw, MANC, manc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
e1000_release_manageability(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	if (adapter->en_mng_pt) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		uint32_t manc = E1000_READ_REG(&adapter->hw, MANC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		/* re-enable hardware interception of ARP */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		manc |= E1000_MANC_ARP_EN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		if (adapter->hw.has_manc2h)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
			manc &= ~E1000_MANC_EN_MNG2HOST;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
		/* don't explicitly have to mess with MANC2H since
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
		 * MANC has an enable disable that gates MANC2H */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
		E1000_WRITE_REG(&adapter->hw, MANC, manc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
e1000_up(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	/* hardware has been reset, we need to reload some things */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	e1000_set_multi(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	e1000_restore_vlan(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	e1000_init_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	e1000_configure_tx(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	e1000_setup_rctl(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	e1000_configure_rx(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	/* call E1000_DESC_UNUSED which always leaves
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	 * at least 1 descriptor unused to make sure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	 * next_to_use != next_to_clean */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	for (i = 0; i < adapter->num_rx_queues; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   562
		if (adapter->ecdev) {
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   563
			/* fill rx ring completely! */
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   564
			adapter->alloc_rx_buf(adapter, ring, ring->count);
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   565
		} else {
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   566
            /* this one leaves the last ring element unallocated! */
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   567
			adapter->alloc_rx_buf(adapter, ring,
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   568
					E1000_DESC_UNUSED(ring));
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
   569
		}
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	adapter->tx_queue_len = netdev->tx_queue_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
    if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
        netif_poll_enable(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
        e1000_irq_enable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
    }
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	clear_bit(__E1000_DOWN, &adapter->flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	/* fire a link change interrupt to start the watchdog */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
 * e1000_power_up_phy - restore link in case the phy was powered down
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
 * The phy may be powered down to save power and turn off link when the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
 * driver is unloaded and wake on lan is not enabled (among others)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
 * *** this routine MUST be followed by a call to e1000_reset ***
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
void e1000_power_up_phy(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	uint16_t mii_reg = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	/* Just clear the power down bit to wake the phy back up */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	if (adapter->hw.media_type == e1000_media_type_copper) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
		/* according to the manual, the phy will retain its
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		 * settings across a power-down/up cycle */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		mii_reg &= ~MII_CR_POWER_DOWN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
static void e1000_power_down_phy(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	/* Power down the PHY so no link is implied when interface is down *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	 * The PHY cannot be powered down if any of the following is TRUE *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	 * (a) WoL is enabled
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	 * (b) AMT is active
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	 * (c) SoL/IDER session is active */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	   adapter->hw.media_type == e1000_media_type_copper) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
		uint16_t mii_reg = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		case e1000_82540:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		case e1000_82545:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		case e1000_82545_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		case e1000_82546:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		case e1000_82546_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		case e1000_82541:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		case e1000_82541_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		case e1000_82547:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		case e1000_82547_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
			if (E1000_READ_REG(&adapter->hw, MANC) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
			    E1000_MANC_SMBUS_EN)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
				goto out;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			if (e1000_check_mng_mode(&adapter->hw) ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
			    e1000_check_phy_reset_block(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
				goto out;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
			goto out;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		mii_reg |= MII_CR_POWER_DOWN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		mdelay(1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
out:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
e1000_down(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	/* signal that we're down so the interrupt handler does not
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	 * reschedule our watchdog timer */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	set_bit(__E1000_DOWN, &adapter->flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
    if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		e1000_irq_disable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
        del_timer_sync(&adapter->tx_fifo_stall_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
        del_timer_sync(&adapter->watchdog_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
        del_timer_sync(&adapter->phy_info_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
        netif_poll_disable(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	netdev->tx_queue_len = adapter->tx_queue_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	adapter->link_speed = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	adapter->link_duplex = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		netif_carrier_off(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	e1000_clean_all_tx_rings(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	e1000_clean_all_rx_rings(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
e1000_reinit_locked(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	WARN_ON(in_interrupt());
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		msleep(1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	e1000_down(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	e1000_up(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	clear_bit(__E1000_RESETTING, &adapter->flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
e1000_reset(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	uint32_t pba = 0, tx_space, min_tx_space, min_rx_space;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	boolean_t legacy_pba_adjust = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	/* Repartition Pba for greater than 9k mtu
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	 * To take effect CTRL.RST is required.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	case e1000_82542_rev2_0:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	case e1000_82542_rev2_1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	case e1000_82543:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	case e1000_82544:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	case e1000_82540:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	case e1000_82541:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	case e1000_82541_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		legacy_pba_adjust = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		pba = E1000_PBA_48K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	case e1000_82545:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	case e1000_82545_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	case e1000_82546:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	case e1000_82546_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
		pba = E1000_PBA_48K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	case e1000_82547:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	case e1000_82547_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		legacy_pba_adjust = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		pba = E1000_PBA_30K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		pba = E1000_PBA_38K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		pba = E1000_PBA_20K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		pba = E1000_PBA_8K;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	case e1000_undefined:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	case e1000_num_macs:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	if (legacy_pba_adjust == TRUE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
			pba -= 8; /* allocate more FIFO for Tx */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
		if (adapter->hw.mac_type == e1000_82547) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
			adapter->tx_fifo_head = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
			adapter->tx_fifo_size =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
			atomic_set(&adapter->tx_fifo_stall, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	} else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		/* adjust PBA for jumbo frames */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		E1000_WRITE_REG(&adapter->hw, PBA, pba);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		/* To maintain wire speed transmits, the Tx FIFO should be
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		 * large enough to accomodate two full transmit packets,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		 * the Rx FIFO should be large enough to accomodate at least
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		 * one full receive packet and is similarly rounded up and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		 * expressed in KB. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		pba = E1000_READ_REG(&adapter->hw, PBA);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		/* upper 16 bits has Tx packet buffer allocation size in KB */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
		tx_space = pba >> 16;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		/* lower 16 bits has Rx packet buffer allocation size in KB */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		pba &= 0xffff;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		/* don't include ethernet FCS because hardware appends/strips */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		               VLAN_TAG_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		min_tx_space = min_rx_space;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		min_tx_space *= 2;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		E1000_ROUNDUP(min_tx_space, 1024);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		min_tx_space >>= 10;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		E1000_ROUNDUP(min_rx_space, 1024);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		min_rx_space >>= 10;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		/* If current Tx allocation is less than the min Tx FIFO size,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		 * and the min Tx FIFO size is less than the current Rx FIFO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		 * allocation, take space away from current Rx allocation */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		if (tx_space < min_tx_space &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		    ((min_tx_space - tx_space) < pba)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
			pba = pba - (min_tx_space - tx_space);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
			/* PCI/PCIx hardware has PBA alignment constraints */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
			switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
			case e1000_82545 ... e1000_82546_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
				pba &= ~(E1000_PBA_8K - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
			default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
			/* if short on rx space, rx wins and must trump tx
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
			 * adjustment or use Early Receive if available */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			if (pba < min_rx_space) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
				switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
				case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
					/* ERT enabled in e1000_configure_rx */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
				default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
					pba = min_rx_space;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	E1000_WRITE_REG(&adapter->hw, PBA, pba);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	/* flow control settings */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	/* Set the FC high water mark to 90% of the FIFO size.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	 * Required to clear last 3 LSB */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	/* We can't use 90% on small FIFOs because the remainder
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	 * would be less than 1 full frame.  In this case, we size
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	 * it to allow at least a full frame above the high water
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	 *  mark. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	if (pba < E1000_PBA_16K)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		fc_high_water_mark = (pba * 1024) - 1600;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	adapter->hw.fc_high_water = fc_high_water_mark;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	adapter->hw.fc_low_water = fc_high_water_mark - 8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	if (adapter->hw.mac_type == e1000_80003es2lan)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
		adapter->hw.fc_pause_time = 0xFFFF;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	adapter->hw.fc_send_xon = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	adapter->hw.fc = adapter->hw.original_fc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	/* Allow time for pending master requests to run */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	e1000_reset_hw(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	if (adapter->hw.mac_type >= e1000_82544)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		E1000_WRITE_REG(&adapter->hw, WUC, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	if (e1000_init_hw(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		DPRINTK(PROBE, ERR, "Hardware Error\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	e1000_update_mng_vlan(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	if (adapter->hw.mac_type >= e1000_82544 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	    adapter->hw.mac_type <= e1000_82547_rev_2 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
	    adapter->hw.autoneg == 1 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	    adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
		/* clear phy power management bit if we are in gig only mode,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
		 * which if enabled will attempt negotiation to 100Mb, which
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
		 * can cause a loss of link at power off or driver unload */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
		ctrl &= ~E1000_CTRL_SWDPIN3;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	e1000_reset_adaptive(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	if (!adapter->smart_power_down &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	    (adapter->hw.mac_type == e1000_82571 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	     adapter->hw.mac_type == e1000_82572)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		uint16_t phy_data = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		/* speed up time to link by disabling smart power down, ignore
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		 * the return value of this function because there is nothing
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		 * different we would do if it failed */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		                   &phy_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		phy_data &= ~IGP02E1000_PM_SPD;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		                    phy_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	e1000_release_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
 * e1000_probe - Device Initialization Routine
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
 * @pdev: PCI device information struct
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
 * @ent: entry in e1000_pci_tbl
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
 * Returns 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
 * e1000_probe initializes an adapter identified by a pci_dev structure.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
 * The OS initialization, configuring of the adapter private structure,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
 * and a hardware reset occur.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
static int __devinit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
e1000_probe(struct pci_dev *pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
            const struct pci_device_id *ent)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	struct net_device *netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	struct e1000_adapter *adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	unsigned long mmio_start, mmio_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	unsigned long flash_start, flash_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	static int cards_found = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	int i, err, pci_using_dac;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	uint16_t eeprom_data = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	if ((err = pci_enable_device(pdev)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
		return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	    !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
		pci_using_dac = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		    (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
			E1000_ERR("No usable DMA configuration, aborting\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
			goto err_dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		pci_using_dac = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	if ((err = pci_request_regions(pdev, e1000_driver_name)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		goto err_pci_reg;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	pci_set_master(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	err = -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	if (!netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		goto err_alloc_etherdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
	SET_MODULE_OWNER(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	SET_NETDEV_DEV(netdev, &pdev->dev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	pci_set_drvdata(pdev, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	adapter->netdev = netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	adapter->pdev = pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	adapter->hw.back = adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	adapter->msg_enable = (1 << debug) - 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	mmio_start = pci_resource_start(pdev, BAR_0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	mmio_len = pci_resource_len(pdev, BAR_0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	err = -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	if (!adapter->hw.hw_addr)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		goto err_ioremap;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	for (i = BAR_1; i <= BAR_5; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		if (pci_resource_len(pdev, i) == 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
			continue;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
			adapter->hw.io_base = pci_resource_start(pdev, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	netdev->open = &e1000_open;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	netdev->stop = &e1000_close;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	netdev->hard_start_xmit = &e1000_xmit_frame;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	netdev->get_stats = &e1000_get_stats;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	netdev->set_multicast_list = &e1000_set_multi;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	netdev->set_mac_address = &e1000_set_mac;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	netdev->change_mtu = &e1000_change_mtu;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	netdev->do_ioctl = &e1000_ioctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	e1000_set_ethtool_ops(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	netdev->tx_timeout = &e1000_tx_timeout;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	netdev->watchdog_timeo = 5 * HZ;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	netdev->poll = &e1000_clean;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	netdev->weight = 64;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	netdev->vlan_rx_register = e1000_vlan_rx_register;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
#ifdef CONFIG_NET_POLL_CONTROLLER
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	netdev->poll_controller = e1000_netpoll;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	netdev->mem_start = mmio_start;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	netdev->mem_end = mmio_start + mmio_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	netdev->base_addr = adapter->hw.io_base;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	adapter->bd_number = cards_found;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	/* setup the private structure */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	if ((err = e1000_sw_init(adapter)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		goto err_sw_init;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	err = -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	/* Flash BAR mapping must happen after e1000_sw_init
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	 * because it depends on mac_type */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	if ((adapter->hw.mac_type == e1000_ich8lan) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		flash_start = pci_resource_start(pdev, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
		flash_len = pci_resource_len(pdev, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		if (!adapter->hw.flash_address)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
			goto err_flashmap;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	if (e1000_check_phy_reset_block(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	if (adapter->hw.mac_type >= e1000_82543) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		netdev->features = NETIF_F_SG |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
				   NETIF_F_HW_CSUM |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
				   NETIF_F_HW_VLAN_TX |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
				   NETIF_F_HW_VLAN_RX |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
				   NETIF_F_HW_VLAN_FILTER;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		if (adapter->hw.mac_type == e1000_ich8lan)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	if ((adapter->hw.mac_type >= e1000_82544) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	   (adapter->hw.mac_type != e1000_82547))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		netdev->features |= NETIF_F_TSO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
#ifdef NETIF_F_TSO6
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	if (adapter->hw.mac_type > e1000_82547_rev_2)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		netdev->features |= NETIF_F_TSO6;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	if (pci_using_dac)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		netdev->features |= NETIF_F_HIGHDMA;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	netdev->features |= NETIF_F_LLTX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	/* initialize eeprom parameters */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	if (e1000_init_eeprom_params(&adapter->hw)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		E1000_ERR("EEPROM initialization failed\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		goto err_eeprom;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* before reading the EEPROM, reset the controller to
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	 * put the device in a known good starting state */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	e1000_reset_hw(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	/* make sure the EEPROM is good */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		goto err_eeprom;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	/* copy the MAC address out of the EEPROM */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	if (e1000_read_mac_addr(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	if (!is_valid_ether_addr(netdev->perm_addr)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		goto err_eeprom;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	e1000_get_bus_info(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	init_timer(&adapter->tx_fifo_stall_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	adapter->tx_fifo_stall_timer.data = (unsigned long) adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	init_timer(&adapter->watchdog_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	adapter->watchdog_timer.function = &e1000_watchdog;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	adapter->watchdog_timer.data = (unsigned long) adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	init_timer(&adapter->phy_info_timer);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	adapter->phy_info_timer.function = &e1000_update_phy_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	adapter->phy_info_timer.data = (unsigned long) adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	e1000_check_options(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	/* Initial Wake on LAN setting
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	 * If APM wake is enabled in the EEPROM,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	 * enable the ACPI Magic Packet filter
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	case e1000_82542_rev2_0:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	case e1000_82542_rev2_1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	case e1000_82543:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	case e1000_82544:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		e1000_read_eeprom(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		e1000_read_eeprom(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	case e1000_82546:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	case e1000_82546_rev_3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
			e1000_read_eeprom(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		/* Fall Through */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		e1000_read_eeprom(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	if (eeprom_data & eeprom_apme_mask)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		adapter->eeprom_wol |= E1000_WUFC_MAG;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	/* now that we have the eeprom settings, apply the special cases
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	 * where the eeprom may be wrong or the board simply won't support
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	 * wake on lan on a particular port */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	switch (pdev->device) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	case E1000_DEV_ID_82546GB_PCIE:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		adapter->eeprom_wol = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	case E1000_DEV_ID_82546EB_FIBER:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	case E1000_DEV_ID_82546GB_FIBER:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	case E1000_DEV_ID_82571EB_FIBER:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		/* Wake events only supported on port A for dual fiber
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		 * regardless of eeprom setting */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
		if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			adapter->eeprom_wol = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		/* if quad port adapter, disable WoL on all but port A */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		if (global_quad_port_a != 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
			adapter->eeprom_wol = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			adapter->quad_port_a = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		/* Reset for multiple quad port adapters */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		if (++global_quad_port_a == 4)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			global_quad_port_a = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	/* initialize the wol settings based on the eeprom settings */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	adapter->wol = adapter->eeprom_wol;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	/* print bus type/speed/width info */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		 "32-bit"));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	for (i = 0; i < 6; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	/* reset the hardware with the new settings */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	/* If the controller is 82573 and f/w is AMT, do not set
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	 * DRV_LOAD until the interface is up.  For all other cases,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	 * let the f/w know that the h/w is now under the control
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	 * of the driver. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	if (adapter->hw.mac_type != e1000_82573 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	    !e1000_check_mng_mode(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		e1000_get_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	// offer device to EtherCAT master module
1011
a0759d0dded4 Improved ecdev_offer().
Florian Pose <fp@igh-essen.com>
parents: 694
diff changeset
  1191
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		if (ecdev_open(adapter->ecdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
			ecdev_withdraw(adapter->ecdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
			goto err_register;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		strcpy(netdev->name, "eth%d");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		if ((err = register_netdev(netdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
			goto err_register;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		/* tell the stack to leave us alone until e1000_open() is called */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		netif_carrier_off(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	cards_found++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
err_register:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	e1000_release_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
err_eeprom:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	if (!e1000_check_phy_reset_block(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		e1000_phy_hw_reset(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	if (adapter->hw.flash_address)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		iounmap(adapter->hw.flash_address);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
err_flashmap:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	for (i = 0; i < adapter->num_rx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		dev_put(&adapter->polling_netdev[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	kfree(adapter->tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	kfree(adapter->rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	kfree(adapter->polling_netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
err_sw_init:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	iounmap(adapter->hw.hw_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
err_ioremap:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	free_netdev(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
err_alloc_etherdev:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	pci_release_regions(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
err_pci_reg:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
err_dma:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	pci_disable_device(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
 * e1000_remove - Device Removal Routine
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
 * @pdev: PCI device information struct
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
 * e1000_remove is called by the PCI subsystem to alert the driver
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
 * that it should release a PCI device.  The could be caused by a
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
 * Hot-Plug event, or because the driver is going to be removed from
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
 * memory.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
static void __devexit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
e1000_remove(struct pci_dev *pdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	flush_scheduled_work();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	e1000_release_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	 * would have already happened in close and is redundant. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	e1000_release_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		ecdev_close(adapter->ecdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		ecdev_withdraw(adapter->ecdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		unregister_netdev(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	for (i = 0; i < adapter->num_rx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		dev_put(&adapter->polling_netdev[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	if (!e1000_check_phy_reset_block(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		e1000_phy_hw_reset(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	kfree(adapter->tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	kfree(adapter->rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	kfree(adapter->polling_netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	iounmap(adapter->hw.hw_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	if (adapter->hw.flash_address)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		iounmap(adapter->hw.flash_address);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	pci_release_regions(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	free_netdev(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	pci_disable_device(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
 * @adapter: board private structure to initialize
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
 * e1000_sw_init initializes the Adapter private data structure.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
 * Fields are initialized based on PCI device information and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
 * OS network device settings (MTU size).
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
static int __devinit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
e1000_sw_init(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	/* PCI config space info */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	hw->vendor_id = pdev->vendor;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	hw->device_id = pdev->device;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	hw->subsystem_id = pdev->subsystem_device;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	hw->max_frame_size = netdev->mtu +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	/* identify the MAC */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	if (e1000_set_mac_type(hw)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		return -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	switch (hw->mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	case e1000_82541:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	case e1000_82547:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	case e1000_82541_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	case e1000_82547_rev_2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		hw->phy_init_script = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	e1000_set_media_type(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	hw->wait_autoneg_complete = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	hw->tbi_compatibility_en = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	hw->adaptive_ifs = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	/* Copper options */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	if (hw->media_type == e1000_media_type_copper) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		hw->mdix = AUTO_ALL_MODES;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		hw->disable_polarity_correction = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		hw->master_slave = E1000_MASTER_SLAVE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	adapter->num_tx_queues = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	adapter->num_rx_queues = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	if (e1000_alloc_queues(adapter)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	for (i = 0; i < adapter->num_rx_queues; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
		adapter->polling_netdev[i].priv = adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		adapter->polling_netdev[i].poll = &e1000_clean;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		adapter->polling_netdev[i].weight = 64;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		dev_hold(&adapter->polling_netdev[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	spin_lock_init(&adapter->tx_queue_lock);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
	atomic_set(&adapter->irq_sem, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	spin_lock_init(&adapter->stats_lock);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	set_bit(__E1000_DOWN, &adapter->flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * e1000_alloc_queues - Allocate memory for all rings
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 * @adapter: board private structure to initialize
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
 * We allocate one ring per queue at run-time since we don't know the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
 * number of queues at compile-time.  The polling_netdev array is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 * intended for Multiqueue, but should work fine with a single queue.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
static int __devinit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
e1000_alloc_queues(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	int size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	if (!adapter->tx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	memset(adapter->tx_ring, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	if (!adapter->rx_ring) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		kfree(adapter->tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	memset(adapter->rx_ring, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	size = sizeof(struct net_device) * adapter->num_rx_queues;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	if (!adapter->polling_netdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		kfree(adapter->tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		kfree(adapter->rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	memset(adapter->polling_netdev, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	return E1000_SUCCESS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
 * e1000_open - Called when a network interface is made active
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
 * Returns 0 on success, negative value on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
 * The open entry point is called when a network interface is made
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
 * active by the system (IFF_UP).  At this point all resources needed
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
 * for transmit and receive operations are allocated, the interrupt
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
 * handler is registered with the OS, the watchdog timer is started,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 * and the stack is notified that the interface is ready.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
e1000_open(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	int err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	/* disallow open during test */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	if (test_bit(__E1000_TESTING, &adapter->flags))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		return -EBUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	/* allocate transmit descriptors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	if ((err = e1000_setup_all_tx_resources(adapter)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		goto err_setup_tx;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	/* allocate receive descriptors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	if ((err = e1000_setup_all_rx_resources(adapter)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		goto err_setup_rx;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	err = e1000_request_irq(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	if (err)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		goto err_req_irq;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	e1000_power_up_phy(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	if ((err = e1000_up(adapter)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		goto err_up;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	if ((adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
		e1000_update_mng_vlan(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	/* If AMT is enabled, let the firmware know that the network
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	 * interface is now open */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	if (adapter->hw.mac_type == e1000_82573 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	    e1000_check_mng_mode(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
		e1000_get_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	return E1000_SUCCESS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
err_up:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	e1000_power_down_phy(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	e1000_free_irq(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
err_req_irq:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	e1000_free_all_rx_resources(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
err_setup_rx:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	e1000_free_all_tx_resources(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
err_setup_tx:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
 * e1000_close - Disables a network interface
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
 * Returns 0, this is not allowed to fail
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
 * The close entry point is called when an interface is de-activated
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
 * by the OS.  The hardware is still under the drivers control, but
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
 * needs to be disabled.  A global MAC reset is issued to stop the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
 * hardware, and all transmit and receive resources are freed.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
e1000_close(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	e1000_down(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	e1000_power_down_phy(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	e1000_free_irq(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	e1000_free_all_tx_resources(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	e1000_free_all_rx_resources(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	/* kill manageability vlan ID if supported, but not if a vlan with
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	 * the same ID is registered on the host OS (let 8021q kill it) */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
	if ((adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	     !(adapter->vlgrp &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
			  adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	/* If AMT is enabled, let the firmware know that the network
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	 * interface is now closed */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	if (adapter->hw.mac_type == e1000_82573 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	    e1000_check_mng_mode(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		e1000_release_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
 * @start: address of beginning of memory
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
 * @len: length of memory
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
static boolean_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
e1000_check_64k_bound(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		      void *start, unsigned long len)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	unsigned long begin = (unsigned long) start;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	unsigned long end = begin + len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	/* First rev 82545 and 82546 need to not allow any memory
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	 * write location to cross 64k boundary due to errata 23 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	if (adapter->hw.mac_type == e1000_82545 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	    adapter->hw.mac_type == e1000_82546) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	return TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
 * @txdr:    tx descriptor ring (for a specific queue) to setup
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
 * Return 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
e1000_setup_tx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
                         struct e1000_tx_ring *txdr)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	int size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
	size = sizeof(struct e1000_buffer) * txdr->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	txdr->buffer_info = vmalloc(size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	if (!txdr->buffer_info) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		"Unable to allocate memory for the transmit descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	memset(txdr->buffer_info, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	/* round up to nearest 4K */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	E1000_ROUNDUP(txdr->size, 4096);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	if (!txdr->desc) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
setup_tx_desc_die:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		vfree(txdr->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		"Unable to allocate memory for the transmit descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	/* Fix for errata 23, can't cross 64kB boundary */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		void *olddesc = txdr->desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		dma_addr_t olddma = txdr->dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
				     "at %p\n", txdr->size, txdr->desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		/* Try again, without freeing the previous */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		/* Failed allocation, critical failure */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		if (!txdr->desc) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
			goto setup_tx_desc_die;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
			/* give up */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
			pci_free_consistent(pdev, txdr->size, txdr->desc,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
					    txdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
				"Unable to allocate aligned memory "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
				"for the transmit descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
			vfree(txdr->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
			/* Free old allocation, new allocation was successful */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	memset(txdr->desc, 0, txdr->size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
	txdr->next_to_use = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	txdr->next_to_clean = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	spin_lock_init(&txdr->tx_lock);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * 				  (Descriptors) for all queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 * Return 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	int i, err = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	for (i = 0; i < adapter->num_tx_queues; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
		if (err) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
				"Allocation for Tx Queue %u failed\n", i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
			for (i-- ; i >= 0; i--)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
				e1000_free_tx_resources(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
							&adapter->tx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
	return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
 * Configure the Tx unit of the MAC after a reset.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
e1000_configure_tx(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	uint64_t tdba;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	uint32_t tdlen, tctl, tipg, tarc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	uint32_t ipgr1, ipgr2;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	/* Setup the HW Tx Head and Tail descriptor pointers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	switch (adapter->num_tx_queues) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	case 1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		tdba = adapter->tx_ring[0].dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		tdlen = adapter->tx_ring[0].count *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
			sizeof(struct e1000_tx_desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
		E1000_WRITE_REG(hw, TDLEN, tdlen);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		E1000_WRITE_REG(hw, TDT, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		E1000_WRITE_REG(hw, TDH, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	/* Set the default values for the Tx Inter Packet Gap timer */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	if (adapter->hw.mac_type <= e1000_82547_rev_2 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	    (hw->media_type == e1000_media_type_fiber ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	     hw->media_type == e1000_media_type_internal_serdes))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	switch (hw->mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	case e1000_82542_rev2_0:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	case e1000_82542_rev2_1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		tipg = DEFAULT_82542_TIPG_IPGT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	E1000_WRITE_REG(hw, TIPG, tipg);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	/* Set the Tx Interrupt Delay register */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	if (hw->mac_type >= e1000_82540)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	/* Program the Transmit Control Register */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	tctl = E1000_READ_REG(hw, TCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	tctl &= ~E1000_TCTL_CT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		tarc = E1000_READ_REG(hw, TARC0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		/* set the speed mode bit, we'll clear it if we're not at
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		 * gigabit link later */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		tarc |= (1 << 21);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		E1000_WRITE_REG(hw, TARC0, tarc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	} else if (hw->mac_type == e1000_80003es2lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		tarc = E1000_READ_REG(hw, TARC0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		tarc |= 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		E1000_WRITE_REG(hw, TARC0, tarc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		tarc = E1000_READ_REG(hw, TARC1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		tarc |= 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		E1000_WRITE_REG(hw, TARC1, tarc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	e1000_config_collision_dist(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	/* Setup Transmit Descriptor Settings for eop descriptor */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	/* only set IDE if we are delaying interrupts using the timers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	if (adapter->tx_int_delay)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	if (hw->mac_type < e1000_82543)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	/* Cache if we're 82544 running in PCI-X because we'll
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	 * need this to apply a workaround later in the send path. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	if (hw->mac_type == e1000_82544 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	    hw->bus_type == e1000_bus_type_pcix)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		adapter->pcix_82544 = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	E1000_WRITE_REG(hw, TCTL, tctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
 * Returns 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
e1000_setup_rx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
                         struct e1000_rx_ring *rxdr)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	int size, desc_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	size = sizeof(struct e1000_buffer) * rxdr->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	rxdr->buffer_info = vmalloc(size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	if (!rxdr->buffer_info) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		"Unable to allocate memory for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	memset(rxdr->buffer_info, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	size = sizeof(struct e1000_ps_page) * rxdr->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	rxdr->ps_page = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	if (!rxdr->ps_page) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		vfree(rxdr->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		"Unable to allocate memory for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
	memset(rxdr->ps_page, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	if (!rxdr->ps_page_dma) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		vfree(rxdr->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		kfree(rxdr->ps_page);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		"Unable to allocate memory for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
	memset(rxdr->ps_page_dma, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	if (adapter->hw.mac_type <= e1000_82547_rev_2)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
		desc_len = sizeof(struct e1000_rx_desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		desc_len = sizeof(union e1000_rx_desc_packet_split);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	/* Round up to nearest 4K */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	rxdr->size = rxdr->count * desc_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	E1000_ROUNDUP(rxdr->size, 4096);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	if (!rxdr->desc) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		"Unable to allocate memory for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
setup_rx_desc_die:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		vfree(rxdr->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		kfree(rxdr->ps_page);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		kfree(rxdr->ps_page_dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	/* Fix for errata 23, can't cross 64kB boundary */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
		void *olddesc = rxdr->desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		dma_addr_t olddma = rxdr->dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
				     "at %p\n", rxdr->size, rxdr->desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		/* Try again, without freeing the previous */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		/* Failed allocation, critical failure */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		if (!rxdr->desc) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
				"Unable to allocate memory "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
				"for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
			goto setup_rx_desc_die;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
			/* give up */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
					    rxdr->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
				"Unable to allocate aligned memory "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
				"for the receive descriptor ring\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			goto setup_rx_desc_die;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
			/* Free old allocation, new allocation was successful */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	memset(rxdr->desc, 0, rxdr->size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	rxdr->next_to_clean = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	rxdr->next_to_use = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
 * 				  (Descriptors) for all queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
 * Return 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	int i, err = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	for (i = 0; i < adapter->num_rx_queues; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
		if (err) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
				"Allocation for Rx Queue %u failed\n", i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
			for (i-- ; i >= 0; i--)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
				e1000_free_rx_resources(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
							&adapter->rx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
 * e1000_setup_rctl - configure the receive control registers
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
 * @adapter: Board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
e1000_setup_rctl(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	uint32_t rctl, rfctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	uint32_t psrctl = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	uint32_t pages = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		(adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	if (adapter->hw.tbi_compatibility_on == 1)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		rctl |= E1000_RCTL_SBP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		rctl &= ~E1000_RCTL_SBP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		rctl &= ~E1000_RCTL_LPE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
		rctl |= E1000_RCTL_LPE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	/* Setup buffer sizes */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	rctl &= ~E1000_RCTL_SZ_4096;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	rctl |= E1000_RCTL_BSEX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	switch (adapter->rx_buffer_len) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		case E1000_RXBUFFER_256:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
			rctl |= E1000_RCTL_SZ_256;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
			rctl &= ~E1000_RCTL_BSEX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		case E1000_RXBUFFER_512:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
			rctl |= E1000_RCTL_SZ_512;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
			rctl &= ~E1000_RCTL_BSEX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		case E1000_RXBUFFER_1024:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
			rctl |= E1000_RCTL_SZ_1024;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
			rctl &= ~E1000_RCTL_BSEX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		case E1000_RXBUFFER_2048:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
			rctl |= E1000_RCTL_SZ_2048;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
			rctl &= ~E1000_RCTL_BSEX;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		case E1000_RXBUFFER_4096:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
			rctl |= E1000_RCTL_SZ_4096;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		case E1000_RXBUFFER_8192:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			rctl |= E1000_RCTL_SZ_8192;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		case E1000_RXBUFFER_16384:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
			rctl |= E1000_RCTL_SZ_16384;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	/* 82571 and greater support packet-split where the protocol
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	 * header is placed in skb->data and the packet data is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	 * In the case of a non-split, skb->data is linearly filled,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	 * followed by the page buffers.  Therefore, skb->data is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	 * sized to hold the largest protocol header.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	/* allocations using alloc_page take too long for regular MTU
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	 * so only enable packet split for jumbo frames */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	if ((adapter->hw.mac_type >= e1000_82571) && (pages <= 3) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	    PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		adapter->rx_ps_pages = pages;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
		adapter->rx_ps_pages = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	if (adapter->rx_ps_pages) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		/* Configure extra packet-split registers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
		rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
		rfctl |= E1000_RFCTL_EXTEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
		/* disable packet split support for IPv6 extension headers,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
		 * because some malformed IPv6 headers can hang the RX */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		          E1000_RFCTL_NEW_IPV6_EXT_DIS);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		rctl |= E1000_RCTL_DTYP_PS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		psrctl |= adapter->rx_ps_bsize0 >>
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
			E1000_PSRCTL_BSIZE0_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		switch (adapter->rx_ps_pages) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		case 3:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
			psrctl |= PAGE_SIZE <<
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
				E1000_PSRCTL_BSIZE3_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
		case 2:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
			psrctl |= PAGE_SIZE <<
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
				E1000_PSRCTL_BSIZE2_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
		case 1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
			psrctl |= PAGE_SIZE >>
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
				E1000_PSRCTL_BSIZE1_SHIFT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
		E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
 * Configure the Rx unit of the MAC after a reset.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
e1000_configure_rx(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	uint64_t rdba;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	uint32_t rdlen, rctl, rxcsum, ctrl_ext;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	if (adapter->rx_ps_pages) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		/* this is a 32 byte descriptor */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		rdlen = adapter->rx_ring[0].count *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
			sizeof(union e1000_rx_desc_packet_split);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		adapter->clean_rx = e1000_clean_rx_irq_ps;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		rdlen = adapter->rx_ring[0].count *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			sizeof(struct e1000_rx_desc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		adapter->clean_rx = e1000_clean_rx_irq;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	/* disable receives while setting up the descriptors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	rctl = E1000_READ_REG(hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	/* set the Receive Delay Timer Register */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	if (hw->mac_type >= e1000_82540) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
		if (adapter->itr_setting != 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
			E1000_WRITE_REG(hw, ITR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
				1000000000 / (adapter->itr * 256));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	if (hw->mac_type >= e1000_82571) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		/* Reset delay timers after every interrupt */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
		/* Auto-Mask interrupts upon ICR access */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		ctrl_ext |= E1000_CTRL_EXT_IAME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
		E1000_WRITE_REG(hw, IAM, 0xffffffff);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		E1000_WRITE_FLUSH(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	 * the Base and Length of the Rx Descriptor Ring */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	switch (adapter->num_rx_queues) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	case 1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		rdba = adapter->rx_ring[0].dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		E1000_WRITE_REG(hw, RDLEN, rdlen);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
		E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		E1000_WRITE_REG(hw, RDT, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		E1000_WRITE_REG(hw, RDH, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	if (hw->mac_type >= e1000_82543) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		rxcsum = E1000_READ_REG(hw, RXCSUM);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		if (adapter->rx_csum == TRUE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			rxcsum |= E1000_RXCSUM_TUOFL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			/* Enable 82571 IPv4 payload checksum for UDP fragments
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
			 * Must be used in conjunction with packet-split. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
			if ((hw->mac_type >= e1000_82571) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			    (adapter->rx_ps_pages)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
				rxcsum |= E1000_RXCSUM_IPPCSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
			rxcsum &= ~E1000_RXCSUM_TUOFL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			/* don't need to clear IPPCSE as it defaults to 0 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	/* enable early receives on 82573, only takes effect if using > 2048
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	 * byte total frame size.  for example only for jumbo frames */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
#define E1000_ERT_2048 0x100
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	if (hw->mac_type == e1000_82573)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
		E1000_WRITE_REG(hw, ERT, E1000_ERT_2048);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	/* Enable Receives */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	E1000_WRITE_REG(hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
 * e1000_free_tx_resources - Free Tx Resources per Queue
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
 * @tx_ring: Tx descriptor ring for a specific queue
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 * Free all transmit software resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
e1000_free_tx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
                        struct e1000_tx_ring *tx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	e1000_clean_tx_ring(adapter, tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	vfree(tx_ring->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	tx_ring->buffer_info = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	tx_ring->desc = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
 * Free all transmit software resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
e1000_free_all_tx_resources(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	for (i = 0; i < adapter->num_tx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			struct e1000_buffer *buffer_info)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	if (buffer_info->dma) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		pci_unmap_page(adapter->pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
				buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
				buffer_info->length,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
				PCI_DMA_TODEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		buffer_info->dma = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	if (buffer_info->skb) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
		dev_kfree_skb_any(buffer_info->skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		buffer_info->skb = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	/* buffer_info must be completely set up in the transmit path */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
 * e1000_clean_tx_ring - Free Tx Buffers
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
 * @tx_ring: ring to be cleaned
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
e1000_clean_tx_ring(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
                    struct e1000_tx_ring *tx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	unsigned long size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	/* Free all the Tx ring sk_buffs */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	for (i = 0; i < tx_ring->count; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	size = sizeof(struct e1000_buffer) * tx_ring->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	memset(tx_ring->buffer_info, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	/* Zero out the descriptor ring */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	memset(tx_ring->desc, 0, tx_ring->size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	tx_ring->next_to_use = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
	tx_ring->next_to_clean = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	tx_ring->last_tx_tso = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	for (i = 0; i < adapter->num_tx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
 * e1000_free_rx_resources - Free Rx Resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
 * @rx_ring: ring to clean the resources from
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
 * Free all receive software resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
e1000_free_rx_resources(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
                        struct e1000_rx_ring *rx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	e1000_clean_rx_ring(adapter, rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	vfree(rx_ring->buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	rx_ring->buffer_info = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	kfree(rx_ring->ps_page);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	rx_ring->ps_page = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	kfree(rx_ring->ps_page_dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	rx_ring->ps_page_dma = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	rx_ring->desc = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
 * Free all receive software resources
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
e1000_free_all_rx_resources(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	for (i = 0; i < adapter->num_rx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
 * @rx_ring: ring to free buffers from
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
e1000_clean_rx_ring(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
                    struct e1000_rx_ring *rx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	struct e1000_ps_page *ps_page;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	struct e1000_ps_page_dma *ps_page_dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	unsigned long size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	unsigned int i, j;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	/* Free all the Rx ring sk_buffs */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	for (i = 0; i < rx_ring->count; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
		if (buffer_info->skb) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
			pci_unmap_single(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
					 buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
					 buffer_info->length,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
					 PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
			dev_kfree_skb(buffer_info->skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
			buffer_info->skb = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		ps_page = &rx_ring->ps_page[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
		ps_page_dma = &rx_ring->ps_page_dma[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		for (j = 0; j < adapter->rx_ps_pages; j++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
			if (!ps_page->ps_page[j]) break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
			pci_unmap_page(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
				       ps_page_dma->ps_page_dma[j],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
				       PAGE_SIZE, PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
			ps_page_dma->ps_page_dma[j] = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
			put_page(ps_page->ps_page[j]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
			ps_page->ps_page[j] = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	size = sizeof(struct e1000_buffer) * rx_ring->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	memset(rx_ring->buffer_info, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	size = sizeof(struct e1000_ps_page) * rx_ring->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	memset(rx_ring->ps_page, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	memset(rx_ring->ps_page_dma, 0, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	/* Zero out the descriptor ring */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	memset(rx_ring->desc, 0, rx_ring->size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	rx_ring->next_to_clean = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	rx_ring->next_to_use = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	writel(0, adapter->hw.hw_addr + rx_ring->rdh);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	writel(0, adapter->hw.hw_addr + rx_ring->rdt);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	for (i = 0; i < adapter->num_rx_queues; i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
 * and memory write and invalidate disabled for certain operations
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
e1000_enter_82542_rst(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	uint32_t rctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	e1000_pci_clear_mwi(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	rctl |= E1000_RCTL_RST;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	E1000_WRITE_FLUSH(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	mdelay(5);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	if (!adapter->ecdev && netif_running(netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
		e1000_clean_all_rx_rings(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
e1000_leave_82542_rst(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	uint32_t rctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	rctl &= ~E1000_RCTL_RST;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	E1000_WRITE_FLUSH(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	mdelay(5);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	if (adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		e1000_pci_set_mwi(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	if (!adapter->netdev && netif_running(netdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		/* No need to loop, because 82542 supports only 1 queue */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		e1000_configure_rx(adapter);
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2406
		if (adapter->ecdev) { 
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2407
			/* fill rx ring completely! */
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2408
			adapter->alloc_rx_buf(adapter, ring, ring->count);
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2409
		} else {
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2410
            /* this one leaves the last ring element unallocated! */
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2411
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2412
		}
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  2413
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
 * e1000_set_mac - Change the Ethernet Address of the NIC
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
 * @p: pointer to an address structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
 * Returns 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
e1000_set_mac(struct net_device *netdev, void *p)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	struct sockaddr *addr = p;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	if (!is_valid_ether_addr(addr->sa_data))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		return -EADDRNOTAVAIL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	/* 82542 2.0 needs to be in reset to write receive address registers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	if (adapter->hw.mac_type == e1000_82542_rev2_0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
		e1000_enter_82542_rst(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	/* With 82571 controllers, LAA may be overwritten (with the default)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
	 * due to controller reset from the other port. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	if (adapter->hw.mac_type == e1000_82571) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
		/* activate the work around */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		adapter->hw.laa_is_present = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		/* Hold a copy of the LAA in RAR[14] This is done so that
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
		 * between the time RAR[0] gets clobbered  and the time it
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		 * of the RARs and no incoming packets directed to this port
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		 * are dropped. Eventaully the LAA will be in RAR[0] and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		 * RAR[14] */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
					E1000_RAR_ENTRIES - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	if (adapter->hw.mac_type == e1000_82542_rev2_0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		e1000_leave_82542_rst(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
 * e1000_set_multi - Multicast and Promiscuous mode set
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
 * The set_multi entry point is called whenever the multicast address
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
 * list or the network interface flags are updated.  This routine is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
 * responsible for configuring the hardware for proper multicast,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
 * promiscuous mode, and all-multi behavior.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
e1000_set_multi(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	struct dev_mc_list *mc_ptr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	uint32_t rctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	uint32_t hash_value;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	int i, rar_entries = E1000_RAR_ENTRIES;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
				E1000_NUM_MTA_REGISTERS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	if (adapter->hw.mac_type == e1000_ich8lan)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	/* reserve RAR[14] for LAA over-write work-around */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	if (adapter->hw.mac_type == e1000_82571)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		rar_entries--;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
	/* Check for Promiscuous and All Multicast modes */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	rctl = E1000_READ_REG(hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	if (netdev->flags & IFF_PROMISC) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	} else if (netdev->flags & IFF_ALLMULTI) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		rctl |= E1000_RCTL_MPE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		rctl &= ~E1000_RCTL_UPE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	E1000_WRITE_REG(hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	/* 82542 2.0 needs to be in reset to write receive address registers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	if (hw->mac_type == e1000_82542_rev2_0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		e1000_enter_82542_rst(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
	/* load the first 14 multicast address into the exact filters 1-14
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
	 * RAR 0 is used for the station MAC adddress
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	 * if there are not 14 addresses, go ahead and clear the filters
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	 * -- with 82571 controllers only 0-13 entries are filled here
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	mc_ptr = netdev->mc_list;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	for (i = 1; i < rar_entries; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		if (mc_ptr) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			mc_ptr = mc_ptr->next;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			E1000_WRITE_FLUSH(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			E1000_WRITE_FLUSH(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	/* clear the old settings from the multicast hash table */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	for (i = 0; i < mta_reg_count; i++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		E1000_WRITE_FLUSH(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	/* load any remaining addresses into the hash table */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
		e1000_mta_set(hw, hash_value);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	if (hw->mac_type == e1000_82542_rev2_0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		e1000_leave_82542_rst(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
/* Need to wait a few seconds after link up to get diagnostic information from
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
 * the phy */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
e1000_update_phy_info(unsigned long data)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
 * e1000_82547_tx_fifo_stall - Timer Call-back
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
 * @data: pointer to adapter cast into an unsigned long
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
e1000_82547_tx_fifo_stall(unsigned long data)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
	uint32_t tctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	if (atomic_read(&adapter->tx_fifo_stall)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		if ((E1000_READ_REG(&adapter->hw, TDT) ==
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
		    E1000_READ_REG(&adapter->hw, TDH)) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		   (E1000_READ_REG(&adapter->hw, TDFT) ==
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		    E1000_READ_REG(&adapter->hw, TDFH)) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		   (E1000_READ_REG(&adapter->hw, TDFTS) ==
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		    E1000_READ_REG(&adapter->hw, TDFHS))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
			tctl = E1000_READ_REG(&adapter->hw, TCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			E1000_WRITE_REG(&adapter->hw, TCTL,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
					tctl & ~E1000_TCTL_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			E1000_WRITE_REG(&adapter->hw, TDFT,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
					adapter->tx_head_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			E1000_WRITE_REG(&adapter->hw, TDFH,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
					adapter->tx_head_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
			E1000_WRITE_REG(&adapter->hw, TDFTS,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
					adapter->tx_head_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
			E1000_WRITE_REG(&adapter->hw, TDFHS,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
					adapter->tx_head_addr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
			E1000_WRITE_FLUSH(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
			adapter->tx_fifo_head = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
			atomic_set(&adapter->tx_fifo_stall, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
			if (!adapter->ecdev) netif_wake_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
			if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
 * e1000_watchdog - Timer Call-back
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
 * @data: pointer to adapter cast into an unsigned long
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
e1000_watchdog(unsigned long data)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	struct e1000_tx_ring *txdr = adapter->tx_ring;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	uint32_t link, tctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	int32_t ret_val;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	ret_val = e1000_check_for_link(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	if ((ret_val == E1000_ERR_PHY) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	    (adapter->hw.phy_type == e1000_phy_igp_3) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	    (E1000_READ_REG(&adapter->hw, CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
		/* See e1000_kumeran_lock_loss_workaround() */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		DPRINTK(LINK, INFO,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
			"Gigabit has been disabled, downgrading speed\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	if (adapter->hw.mac_type == e1000_82573) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
		e1000_enable_tx_pkt_filtering(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
			e1000_update_mng_vlan(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	   !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		link = !adapter->hw.serdes_link_down;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	if (link) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
			boolean_t txb2b = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
			e1000_get_speed_and_duplex(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
			                           &adapter->link_speed,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
			                           &adapter->link_duplex);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
			DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
			       adapter->link_speed,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
			       adapter->link_duplex == FULL_DUPLEX ?
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			       "Full Duplex" : "Half Duplex");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
			/* tweak tx_queue_len according to speed/duplex
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
			 * and adjust the timeout factor */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
			netdev->tx_queue_len = adapter->tx_queue_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
			adapter->tx_timeout_factor = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
			switch (adapter->link_speed) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
			case SPEED_10:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
				txb2b = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
				netdev->tx_queue_len = 10;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
				adapter->tx_timeout_factor = 8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
			case SPEED_100:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
				txb2b = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
				netdev->tx_queue_len = 100;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
				/* maybe add some timeout factor ? */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
			if ((adapter->hw.mac_type == e1000_82571 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
			     adapter->hw.mac_type == e1000_82572) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
			    txb2b == 0) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
				uint32_t tarc0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
				tarc0 = E1000_READ_REG(&adapter->hw, TARC0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
				tarc0 &= ~(1 << 21);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
				E1000_WRITE_REG(&adapter->hw, TARC0, tarc0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
			/* disable TSO for pcie and 10/100 speeds, to avoid
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
			 * some hardware issues */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
			if (!adapter->tso_force &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
			    adapter->hw.bus_type == e1000_bus_type_pci_express){
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
				switch (adapter->link_speed) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
				case SPEED_10:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
				case SPEED_100:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
					DPRINTK(PROBE,INFO,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
				        "10/100 speed: disabling TSO\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
					netdev->features &= ~NETIF_F_TSO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
#ifdef NETIF_F_TSO6
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
					netdev->features &= ~NETIF_F_TSO6;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
				case SPEED_1000:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
					netdev->features |= NETIF_F_TSO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
#ifdef NETIF_F_TSO6
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
					netdev->features |= NETIF_F_TSO6;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
				default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
					/* oops */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
			/* enable transmits in the hardware, need to do this
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
			 * after setting TARC0 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			tctl = E1000_READ_REG(&adapter->hw, TCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
			tctl |= E1000_TCTL_EN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
			E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
			if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
				ecdev_set_link(adapter->ecdev, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
				netif_carrier_on(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
				netif_wake_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
				mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
			adapter->smartspeed = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
			/* make sure the receive unit is started */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
			if (adapter->hw.rx_needs_kicking) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
				struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
				uint32_t rctl = E1000_READ_REG(hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
				E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
			adapter->link_speed = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
			adapter->link_duplex = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
			DPRINTK(LINK, INFO, "NIC Link is Down\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
			if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
				ecdev_set_link(adapter->ecdev, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
				netif_carrier_off(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
				netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
                mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
			/* 80003ES2LAN workaround--
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			 * For packet buffer work-around on link down event;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
			 * disable receives in the ISR and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
			 * reset device here in the watchdog
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
			 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
			if (adapter->hw.mac_type == e1000_80003es2lan)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
				/* reset device */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
				schedule_work(&adapter->reset_task);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		e1000_smartspeed(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	e1000_update_stats(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	adapter->hw.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	adapter->tpt_old = adapter->stats.tpt;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	adapter->colc_old = adapter->stats.colc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	adapter->gorcl_old = adapter->stats.gorcl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	adapter->gotcl_old = adapter->stats.gotcl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	e1000_update_adaptive(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			/* We've lost link, so the controller stops DMA,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
			 * but we've got queued Tx work that's never going
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
			 * to get done, so reset controller to flush Tx.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
			 * (Do the reset outside of interrupt context). */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
			adapter->tx_timeout_count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
			schedule_work(&adapter->reset_task);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	/* Cause software interrupt to ensure rx ring is cleaned */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	/* Force detection of hung controller every watchdog period */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	if (!adapter->ecdev) adapter->detect_tx_hung = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	/* With 82571 controllers, LAA may be overwritten due to controller
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	/* Reset the timer */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
        mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
enum latency_range {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	lowest_latency = 0,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	low_latency = 1,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	bulk_latency = 2,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	latency_invalid = 255
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
};
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
 * e1000_update_itr - update the dynamic ITR value based on statistics
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
 *      Stores a new ITR value based on packets and byte
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
 *      counts during the last interrupt.  The advantage of per interrupt
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
 *      computation is faster updates and more accurate ITR for the current
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
 *      traffic pattern.  Constants in this function were computed
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
 *      based on theoretical maximum wire speed and thresholds were set based
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
 *      on testing data as well as attempting to minimize response time
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
 *      while increasing bulk throughput.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 *      this functionality is controlled by the InterruptThrottleRate module
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 *      parameter (see e1000_param.c)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 * @adapter: pointer to adapter
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
 * @itr_setting: current adapter->itr
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
 * @packets: the number of packets during this measurement interval
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
 * @bytes: the number of bytes during this measurement interval
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
                                   uint16_t itr_setting,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
                                   int packets,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
                                   int bytes)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	unsigned int retval = itr_setting;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	if (unlikely(hw->mac_type < e1000_82540))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		goto update_itr_done;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	if (packets == 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		goto update_itr_done;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	switch (itr_setting) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	case lowest_latency:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		/* jumbo frames get bulk treatment*/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		if (bytes/packets > 8000)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
			retval = bulk_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		else if ((packets < 5) && (bytes > 512))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			retval = low_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	case low_latency:  /* 50 usec aka 20000 ints/s */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		if (bytes > 10000) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
			/* jumbo frames need bulk latency setting */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
			if (bytes/packets > 8000)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
				retval = bulk_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
			else if ((packets < 10) || ((bytes/packets) > 1200))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
				retval = bulk_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
			else if ((packets > 35))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
				retval = lowest_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
		} else if (bytes/packets > 2000)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
			retval = bulk_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		else if (packets <= 2 && bytes < 512)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
			retval = lowest_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	case bulk_latency: /* 250 usec aka 4000 ints/s */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		if (bytes > 25000) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			if (packets > 35)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
				retval = low_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		} else if (bytes < 6000) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
			retval = low_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
update_itr_done:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	return retval;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
static void e1000_set_itr(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	uint16_t current_itr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
	uint32_t new_itr = adapter->itr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	if (unlikely(hw->mac_type < e1000_82540))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	if (unlikely(adapter->link_speed != SPEED_1000)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		current_itr = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		new_itr = 4000;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		goto set_itr_now;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	adapter->tx_itr = e1000_update_itr(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	                            adapter->tx_itr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	                            adapter->total_tx_packets,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	                            adapter->total_tx_bytes);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		adapter->tx_itr = low_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	adapter->rx_itr = e1000_update_itr(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	                            adapter->rx_itr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	                            adapter->total_rx_packets,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	                            adapter->total_rx_bytes);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
		adapter->rx_itr = low_latency;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	switch (current_itr) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	/* counts and packets in update_itr are dependent on these numbers */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	case lowest_latency:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		new_itr = 70000;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	case low_latency:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		new_itr = 20000; /* aka hwitr = ~200 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	case bulk_latency:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		new_itr = 4000;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
set_itr_now:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	if (new_itr != adapter->itr) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		/* this attempts to bias the interrupt rate towards Bulk
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 * by adding intermediate steps when interrupt rate is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		 * increasing */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		new_itr = new_itr > adapter->itr ?
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		             min(adapter->itr + (new_itr >> 2), new_itr) :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		             new_itr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		adapter->itr = new_itr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		E1000_WRITE_REG(hw, ITR, 1000000000 / (new_itr * 256));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
#define E1000_TX_FLAGS_CSUM		0x00000001
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
#define E1000_TX_FLAGS_VLAN		0x00000002
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
#define E1000_TX_FLAGS_TSO		0x00000004
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
#define E1000_TX_FLAGS_IPV4		0x00000008
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
#define E1000_TX_FLAGS_VLAN_SHIFT	16
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
          struct sk_buff *skb)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	struct e1000_context_desc *context_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	uint32_t cmd_length = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	uint16_t ipcse = 0, tucse, mss;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	int err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	if (skb_is_gso(skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
		if (skb_header_cloned(skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
			if (err)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
				return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		mss = skb_shinfo(skb)->gso_size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		if (skb->protocol == htons(ETH_P_IP)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
			skb->nh.iph->tot_len = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
			skb->nh.iph->check = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
			skb->h.th->check =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
				~csum_tcpudp_magic(skb->nh.iph->saddr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
						   skb->nh.iph->daddr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
						   0,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
						   IPPROTO_TCP,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
						   0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
			cmd_length = E1000_TXD_CMD_IP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
			ipcse = skb->h.raw - skb->data - 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
#ifdef NETIF_F_TSO6
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
			skb->nh.ipv6h->payload_len = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
			skb->h.th->check =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
				~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
						 &skb->nh.ipv6h->daddr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
						 0,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
						 IPPROTO_TCP,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
						 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			ipcse = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		ipcss = skb->nh.raw - skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		tucss = skb->h.raw - skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
		tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		tucse = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		i = tx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
		buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
		context_desc->upper_setup.tcp_fields.tucss = tucss;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		context_desc->upper_setup.tcp_fields.tucso = tucso;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		buffer_info->time_stamp = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		buffer_info->next_to_watch = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
		if (++i == tx_ring->count) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
		tx_ring->next_to_use = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		return TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	return FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
static boolean_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
              struct sk_buff *skb)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	struct e1000_context_desc *context_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	uint8_t css;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
		css = skb->h.raw - skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		i = tx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
		context_desc->upper_setup.tcp_fields.tucss = css;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		context_desc->upper_setup.tcp_fields.tucse = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		context_desc->tcp_seg_setup.data = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		buffer_info->time_stamp = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		buffer_info->next_to_watch = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
		if (unlikely(++i == tx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		tx_ring->next_to_use = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		return TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	return FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
#define E1000_MAX_TXD_PWR	12
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
             struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
             unsigned int nr_frags, unsigned int mss)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	unsigned int len = skb->len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	unsigned int offset = 0, size, count = 0, i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	unsigned int f;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	len -= skb->data_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	i = tx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	while (len) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
		buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		size = min(len, max_per_txd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		/* Workaround for Controller erratum --
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		 * descriptor for non-tso packet in a linear SKB that follows a
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		 * tso gets written back prematurely before the data is fully
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		 * DMA'd to the controller */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		if (!skb->data_len && tx_ring->last_tx_tso &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		    !skb_is_gso(skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
			tx_ring->last_tx_tso = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
			size -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		/* Workaround for premature desc write-backs
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		 * in TSO mode.  Append 4-byte sentinel desc */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		if (unlikely(mss && !nr_frags && size == len && size > 8))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
			size -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		/* work-around for errata 10 and it applies
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		 * to all controllers in PCI-X mode
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		 * The fix is to make sure that the first descriptor of a
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
		if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		                (size > 2015) && count == 0))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		        size = 2015;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		 * terminating buffers within evenly-aligned dwords. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
		if (unlikely(adapter->pcix_82544 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		   size > 4))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
			size -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		buffer_info->length = size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		buffer_info->dma =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
			pci_map_single(adapter->pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
				skb->data + offset,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
				size,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
				PCI_DMA_TODEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		buffer_info->time_stamp = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		buffer_info->next_to_watch = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		len -= size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
		offset += size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		if (unlikely(++i == tx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	for (f = 0; f < nr_frags; f++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		struct skb_frag_struct *frag;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		frag = &skb_shinfo(skb)->frags[f];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		len = frag->size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		offset = frag->page_offset;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		while (len) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
			buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
			size = min(len, max_per_txd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
			/* Workaround for premature desc write-backs
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
			 * in TSO mode.  Append 4-byte sentinel desc */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
				size -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
			/* Workaround for potential 82544 hang in PCI-X.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
			 * Avoid terminating buffers within evenly-aligned
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
			 * dwords. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
			if (unlikely(adapter->pcix_82544 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			   size > 4))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
				size -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
			buffer_info->length = size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
			buffer_info->dma =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
				pci_map_page(adapter->pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
					frag->page,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
					offset,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
					size,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
					PCI_DMA_TODEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
			buffer_info->time_stamp = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
			buffer_info->next_to_watch = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
			len -= size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
			offset += size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
			count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
			if (unlikely(++i == tx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	tx_ring->buffer_info[i].skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	tx_ring->buffer_info[first].next_to_watch = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	return count;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
               int tx_flags, int count)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	struct e1000_tx_desc *tx_desc = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
		             E1000_TXD_CMD_TSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		txd_lower |= E1000_TXD_CMD_VLE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	i = tx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	while (count--) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		tx_desc = E1000_TX_DESC(*tx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
		tx_desc->lower.data =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
			cpu_to_le32(txd_lower | buffer_info->length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
		tx_desc->upper.data = cpu_to_le32(txd_upper);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
		if (unlikely(++i == tx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	/* Force memory writes to complete before letting h/w
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	 * know there are new descriptors to fetch.  (Only
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	 * applicable for weak-ordered memory model archs,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	 * such as IA-64). */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	wmb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	tx_ring->next_to_use = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	/* we need this if more than one processor can write to our tail
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	 * at a time, it syncronizes IO on IA64/Altix systems */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	mmiowb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
 * 82547 workaround to avoid controller hang in half-duplex environment.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
 * The workaround is to avoid queuing a large packet that would span
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
 * the internal Tx FIFO ring boundary by notifying the stack to resend
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
 * to the beginning of the Tx FIFO.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
#define E1000_FIFO_HDR			0x10
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
#define E1000_82547_PAD_LEN		0x3E0
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	uint32_t skb_fifo_len = skb->len + E1000_FIFO_HDR;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	if (adapter->link_duplex != HALF_DUPLEX)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		goto no_fifo_stall_required;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	if (atomic_read(&adapter->tx_fifo_stall))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		return 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
		atomic_set(&adapter->tx_fifo_stall, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
		return 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
no_fifo_stall_required:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	adapter->tx_fifo_head += skb_fifo_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
#define MINIMUM_DHCP_PACKET_SIZE 282
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	struct e1000_hw *hw =  &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	uint16_t length, offset;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	if (vlan_tx_tag_present(skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
			( adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
			return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
		struct ethhdr *eth = (struct ethhdr *) skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		if ((htons(ETH_P_IP) == eth->h_proto)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
			const struct iphdr *ip =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
				(struct iphdr *)((uint8_t *)skb->data+14);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
			if (IPPROTO_UDP == ip->protocol) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
				struct udphdr *udp =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
					(struct udphdr *)((uint8_t *)ip +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
						(ip->ihl << 2));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
				if (ntohs(udp->dest) == 67) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
					offset = (uint8_t *)udp + 8 - skb->data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
					length = skb->len - offset;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
					return e1000_mng_write_dhcp_info(hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
							(uint8_t *)udp + 8,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
							length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	/* Herbert's original patch had:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	 *  smp_mb__after_netif_stop_queue();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	 * but since that doesn't exist yet, just open code it. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	smp_mb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	/* We need to check again in a case another CPU has just
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	 * made room available. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		return -EBUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	/* A reprieve! */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	netif_start_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	++adapter->restart_queue;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
static int e1000_maybe_stop_tx(struct net_device *netdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
                               struct e1000_tx_ring *tx_ring, int size)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	return __e1000_maybe_stop_tx(netdev, size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	struct e1000_tx_ring *tx_ring;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	unsigned int tx_flags = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	unsigned int len = skb->len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	unsigned long flags = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	unsigned int nr_frags = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	unsigned int mss = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	int count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	int tso;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	unsigned int f;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	len -= skb->data_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	/* This goes back to the question of how to logically map a tx queue
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	 * to a flow.  Right now, performance is impacted slightly negatively
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	 * if using multiple tx queues.  If the stack breaks away from a
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	 * single qdisc implementation, we can look at this again. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	tx_ring = adapter->tx_ring;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	if (unlikely(skb->len <= 0)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
			dev_kfree_skb_any(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
		return NETDEV_TX_OK;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	/* 82571 and newer doesn't need the workaround that limited descriptor
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	 * length to 4kB */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	if (adapter->hw.mac_type >= e1000_82571)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
		max_per_txd = 8192;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	mss = skb_shinfo(skb)->gso_size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	/* The controller does a simple calculation to
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	 * make sure there is enough room in the FIFO before
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	 * initiating the DMA for each buffer.  The calc is:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	 * 4 = ceil(buffer len/mss).  To make sure we don't
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	 * overrun the FIFO, adjust the max buffer len if mss
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	 * drops. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
	if (mss) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		uint8_t hdr_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		max_per_txd = min(mss << 2, max_per_txd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		max_txd_pwr = fls(max_per_txd) - 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
		* points to just header, pull a few bytes of payload from
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
		* frags into skb->data */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
			switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
				unsigned int pull_size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
			case e1000_82544:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
				/* Make sure we have room to chop off 4 bytes,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
				 * and that the end alignment will work out to
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
				 * this hardware's requirements
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
				 * NOTE: this is a TSO only workaround
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
				 * if end byte alignment not correct move us
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
				 * into the next dword */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
				if ((unsigned long)(skb->tail - 1) & 4)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
				/* fall through */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
			case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
			case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
			case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
			case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
				pull_size = min((unsigned int)4, skb->data_len);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
				if (!__pskb_pull_tail(skb, pull_size)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
					DPRINTK(DRV, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
						"__pskb_pull_tail failed.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
					dev_kfree_skb_any(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
					return NETDEV_TX_OK;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
				len = skb->len - skb->data_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
			default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
				/* do nothing */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	/* reserve a descriptor for the offload context */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
#else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	if (skb->ip_summed == CHECKSUM_PARTIAL)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
#ifdef NETIF_F_TSO
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	/* Controller Erratum workaround */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	count += TXD_USE_COUNT(len, max_txd_pwr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	if (adapter->pcix_82544)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	/* work-around for errata 10 and it applies to all controllers
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	 * in PCI-X mode, so add one more descriptor to the count
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
			(len > 2015)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	nr_frags = skb_shinfo(skb)->nr_frags;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	for (f = 0; f < nr_frags; f++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
				       max_txd_pwr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	if (adapter->pcix_82544)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		count += nr_frags;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	if (adapter->hw.tx_pkt_filtering &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	    (adapter->hw.mac_type == e1000_82573))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		e1000_transfer_dhcp_info(adapter, skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		local_irq_save(flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		if (!spin_trylock(&tx_ring->tx_lock)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			/* Collision - tell upper layer to requeue */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
			local_irq_restore(flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
			return NETDEV_TX_LOCKED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	/* need: count + 2 desc gap to keep tail from touching
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	 * head, otherwise try next time */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
1154
04bcd38cf8dc Fixed missing protection for a spin_lock_irqrestore() call.
Florian Pose <fp@igh-essen.com>
parents: 1152
diff changeset
  3464
		if (!adapter->ecdev) {
04bcd38cf8dc Fixed missing protection for a spin_lock_irqrestore() call.
Florian Pose <fp@igh-essen.com>
parents: 1152
diff changeset
  3465
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
04bcd38cf8dc Fixed missing protection for a spin_lock_irqrestore() call.
Florian Pose <fp@igh-essen.com>
parents: 1152
diff changeset
  3466
		}
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		return NETDEV_TX_BUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
			if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
				netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
				spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
			return NETDEV_TX_BUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		tx_flags |= E1000_TX_FLAGS_VLAN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	first = tx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	tso = e1000_tso(adapter, tx_ring, skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	if (tso < 0) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
		if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
			dev_kfree_skb_any(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
		return NETDEV_TX_OK;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	if (likely(tso)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
		tx_ring->last_tx_tso = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		tx_flags |= E1000_TX_FLAGS_TSO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		tx_flags |= E1000_TX_FLAGS_CSUM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	 * no longer assume, we must. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	if (likely(skb->protocol == htons(ETH_P_IP)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
		tx_flags |= E1000_TX_FLAGS_IPV4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	e1000_tx_queue(adapter, tx_ring, tx_flags,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	               e1000_tx_map(adapter, tx_ring, skb, first,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	                            max_per_txd, nr_frags, mss));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
	netdev->trans_start = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		/* Make sure there is space in the ring for the next send. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	return NETDEV_TX_OK;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
 * e1000_tx_timeout - Respond to a Tx Hang
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
e1000_tx_timeout(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	/* Do the reset outside of interrupt context */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	adapter->tx_timeout_count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	schedule_work(&adapter->reset_task);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
e1000_reset_task(struct work_struct *work)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	struct e1000_adapter *adapter =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		container_of(work, struct e1000_adapter, reset_task);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	e1000_reinit_locked(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
 * e1000_get_stats - Get System Network Statistics
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
 * Returns the address of the device statistics structure.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
 * The statistics are actually updated from the timer callback.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
static struct net_device_stats *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
e1000_get_stats(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	/* only return the current stats */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	return &adapter->net_stats;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
 * e1000_change_mtu - Change the Maximum Transfer Unit
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
 * @netdev: network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
 * @new_mtu: new value for maximum frame size
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
 * Returns 0 on success, negative on failure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
e1000_change_mtu(struct net_device *netdev, int new_mtu)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	uint16_t eeprom_data = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		return -EBUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
		return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	/* Adapter-specific max frame size limits. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	switch (adapter->hw.mac_type) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	case e1000_undefined ... e1000_82542_rev2_1:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	case e1000_ich8lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
			return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	case e1000_82573:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		/* Jumbo Frames not supported if:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		 * - this is not an 82573L device
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
		 * - ASPM is enabled in any way (0x1A bits 3:2) */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		                  &eeprom_data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		if ((adapter->hw.device_id != E1000_DEV_ID_82573L) ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
				DPRINTK(PROBE, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
			            	"Jumbo Frames not supported.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
				return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		/* ERT will be enabled later to enable wire speed receives */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		/* fall through to get support */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
	case e1000_82571:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	case e1000_82572:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	case e1000_80003es2lan:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
#define MAX_STD_JUMBO_FRAME_SIZE 9234
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
			return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	 * means we reserve 2 more, this pushes us to allocate from the next
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	 * larger slab size
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	if (max_frame <= E1000_RXBUFFER_256)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	else if (max_frame <= E1000_RXBUFFER_512)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	else if (max_frame <= E1000_RXBUFFER_1024)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	else if (max_frame <= E1000_RXBUFFER_2048)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	else if (max_frame <= E1000_RXBUFFER_4096)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	else if (max_frame <= E1000_RXBUFFER_8192)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	else if (max_frame <= E1000_RXBUFFER_16384)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	/* adjust allocation if LPE protects us, and we aren't using SBP */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	if (!adapter->hw.tbi_compatibility_on &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	netdev->mtu = new_mtu;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	adapter->hw.max_frame_size = max_frame;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	if (netif_running(netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
		e1000_reinit_locked(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
 * e1000_update_stats - Update the board statistics counters
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
e1000_update_stats(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	unsigned long flags = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	uint16_t phy_tmp;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	/*
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	 * Prevent stats update while adapter is being reset, or if the pci
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	 * connection is down.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	if (adapter->link_speed == 0)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	if (pdev->error_state && pdev->error_state != pci_channel_io_normal)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
		spin_lock_irqsave(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	/* these counters are modified from e1000_adjust_tbi_stats,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	 * called from the interrupt context, so they must only
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	 * be written while holding adapter->stats_lock
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	adapter->stats.crcerrs += E1000_READ_REG(hw, CRCERRS);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	adapter->stats.gprc += E1000_READ_REG(hw, GPRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	adapter->stats.gorcl += E1000_READ_REG(hw, GORCL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	adapter->stats.gorch += E1000_READ_REG(hw, GORCH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	adapter->stats.roc += E1000_READ_REG(hw, ROC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	if (adapter->hw.mac_type != e1000_ich8lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
		adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
		adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
	adapter->stats.mpc += E1000_READ_REG(hw, MPC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	adapter->stats.scc += E1000_READ_REG(hw, SCC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	adapter->stats.ecol += E1000_READ_REG(hw, ECOL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
	adapter->stats.mcc += E1000_READ_REG(hw, MCC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	adapter->stats.latecol += E1000_READ_REG(hw, LATECOL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
	adapter->stats.dc += E1000_READ_REG(hw, DC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	adapter->stats.sec += E1000_READ_REG(hw, SEC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	adapter->stats.rlec += E1000_READ_REG(hw, RLEC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	adapter->stats.xonrxc += E1000_READ_REG(hw, XONRXC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	adapter->stats.xontxc += E1000_READ_REG(hw, XONTXC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	adapter->stats.xoffrxc += E1000_READ_REG(hw, XOFFRXC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	adapter->stats.xofftxc += E1000_READ_REG(hw, XOFFTXC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	adapter->stats.fcruc += E1000_READ_REG(hw, FCRUC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	adapter->stats.gptc += E1000_READ_REG(hw, GPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	adapter->stats.gotcl += E1000_READ_REG(hw, GOTCL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	adapter->stats.gotch += E1000_READ_REG(hw, GOTCH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	adapter->stats.rnbc += E1000_READ_REG(hw, RNBC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	adapter->stats.ruc += E1000_READ_REG(hw, RUC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	adapter->stats.rfc += E1000_READ_REG(hw, RFC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	adapter->stats.rjc += E1000_READ_REG(hw, RJC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	adapter->stats.torl += E1000_READ_REG(hw, TORL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
	adapter->stats.torh += E1000_READ_REG(hw, TORH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	adapter->stats.totl += E1000_READ_REG(hw, TOTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	adapter->stats.toth += E1000_READ_REG(hw, TOTH);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	adapter->stats.tpr += E1000_READ_REG(hw, TPR);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	if (adapter->hw.mac_type != e1000_ich8lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	/* used for adaptive IFS */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
	hw->tx_packet_delta = E1000_READ_REG(hw, TPT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	adapter->stats.tpt += hw->tx_packet_delta;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	hw->collision_delta = E1000_READ_REG(hw, COLC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	adapter->stats.colc += hw->collision_delta;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	if (hw->mac_type >= e1000_82543) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
		adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
		adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
		adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
		adapter->stats.cexterr += E1000_READ_REG(hw, CEXTERR);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
		adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	if (hw->mac_type > e1000_82547_rev_2) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
		adapter->stats.iac += E1000_READ_REG(hw, IAC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
		if (adapter->hw.mac_type != e1000_ich8lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
			adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
			adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
			adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
			adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
			adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
			adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
			adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	/* Fill out the OS statistics structure */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	adapter->net_stats.rx_packets = adapter->stats.gprc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	adapter->net_stats.tx_packets = adapter->stats.gptc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	adapter->net_stats.rx_bytes = adapter->stats.gorcl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	adapter->net_stats.tx_bytes = adapter->stats.gotcl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	adapter->net_stats.multicast = adapter->stats.mprc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	adapter->net_stats.collisions = adapter->stats.colc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	/* Rx Errors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
	/* RLEC on some newer hardware can be incorrect so build
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
	* our own version based on RUC and ROC */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		adapter->stats.crcerrs + adapter->stats.algnerrc +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		adapter->stats.ruc + adapter->stats.roc +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		adapter->stats.cexterr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	/* Tx Errors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	if (adapter->hw.bad_tx_carr_stats_fd &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	    adapter->link_duplex == FULL_DUPLEX) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		adapter->net_stats.tx_carrier_errors = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		adapter->stats.tncrs = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	/* Tx Dropped needs to be maintained elsewhere */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	/* Phy Stats */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	if (hw->media_type == e1000_media_type_copper) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		if ((adapter->link_speed == SPEED_1000) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
			adapter->phy_stats.idle_errors += phy_tmp;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		if ((hw->mac_type <= e1000_82546) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		   (hw->phy_type == e1000_phy_m88) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
			adapter->phy_stats.receive_errors += phy_tmp;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	/* Management Stats */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	if (adapter->hw.has_smbus) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
		adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
		adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	if (!adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
void ec_poll(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
    struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
    if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
        e1000_watchdog((unsigned long) adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
        adapter->ec_watchdog_jiffies = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
    }
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3853
#ifdef CONFIG_PCI_MSI
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3854
	e1000_intr_msi(0, netdev);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3855
#else
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
    e1000_intr(0, netdev);
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3857
#endif
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
#ifdef CONFIG_PCI_MSI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
 * e1000_intr_msi - Interrupt Handler
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
 * @irq: interrupt number
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
 * @data: pointer to a network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
static
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
irqreturn_t e1000_intr_msi(int irq, void *data)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	struct net_device *netdev = data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	int i;
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  3874
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  3875
	if (adapter->ecdev) {
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
#ifdef CONFIG_E1000_NAPI
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  3877
		int ec_work_done = 0;
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  3878
#endif
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3879
		for (i = 0; i < E1000_MAX_INTR; i++)
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3880
#ifdef CONFIG_E1000_NAPI
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3881
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3882
                            &ec_work_done, 100) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3883
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3884
#else
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3885
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3886
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3887
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3888
				break;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3889
	} else {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3890
		/* this code avoids the read of ICR but has to get 1000 interrupts
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3891
		 * at every link change event before it will notice the change */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3892
		if (++adapter->detect_link >= 1000) {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3893
			uint32_t icr = E1000_READ_REG(hw, ICR);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3894
#ifdef CONFIG_E1000_NAPI
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3895
			/* read ICR disables interrupts using IAM, so keep up with our
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3896
			 * enable/disable accounting */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3897
			atomic_inc(&adapter->irq_sem);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3898
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3899
			adapter->detect_link = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3900
			if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) &&
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3901
					(icr & E1000_ICR_INT_ASSERTED)) {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3902
				hw->get_link_status = 1;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3903
				/* 80003ES2LAN workaround--
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3904
				 * For packet buffer work-around on link down event;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3905
				 * disable receives here in the ISR and
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3906
				 * reset adapter in watchdog
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3907
				 */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3908
				if (netif_carrier_ok(netdev) &&
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3909
						(adapter->hw.mac_type == e1000_80003es2lan)) {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3910
					/* disable receives */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3911
					uint32_t rctl = E1000_READ_REG(hw, RCTL);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3912
					E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3913
				}
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3914
				/* guard against interrupt when we're going down */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3915
				if (!test_bit(__E1000_DOWN, &adapter->flags))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3916
					mod_timer(&adapter->watchdog_timer,
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3917
							jiffies + 1);
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
			}
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3919
		} else {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3920
			E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ |
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3921
							E1000_ICR_LSC)));
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3922
			/* bummer we have to flush here, but things break otherwise as
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3923
			 * some event appears to be lost or delayed and throughput
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3924
			 * drops.  In almost all tests this flush is un-necessary */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3925
			E1000_WRITE_FLUSH(hw);
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
#ifdef CONFIG_E1000_NAPI
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3927
			/* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3928
			 * masked.  No need for the IMC write, but it does mean we
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3929
			 * should account for it ASAP. */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3930
			atomic_inc(&adapter->irq_sem);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3931
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3932
		}
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
#ifdef CONFIG_E1000_NAPI
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3935
		if (likely(netif_rx_schedule_prep(netdev))) {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3936
			adapter->total_tx_bytes = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3937
			adapter->total_tx_packets = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3938
			adapter->total_rx_bytes = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3939
			adapter->total_rx_packets = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3940
			__netif_rx_schedule(netdev);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3941
		} else
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3942
			e1000_irq_enable(adapter);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3943
#else
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		adapter->total_tx_bytes = 0;
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3945
		adapter->total_rx_bytes = 0;
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
		adapter->total_tx_packets = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		adapter->total_rx_packets = 0;
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3948
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3949
		for (i = 0; i < E1000_MAX_INTR; i++)
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3950
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3951
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3952
				break;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3953
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3954
		if (likely(adapter->itr_setting & 3))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3955
			e1000_set_itr(adapter);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3956
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  3957
	}
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
	return IRQ_HANDLED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
 * e1000_intr - Interrupt Handler
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
 * @irq: interrupt number
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
 * @data: pointer to a network interface device structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
static irqreturn_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
e1000_intr(int irq, void *data)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	struct net_device *netdev = data;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	struct e1000_hw *hw = &adapter->hw;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	uint32_t rctl, icr = E1000_READ_REG(hw, ICR);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	if (unlikely(!icr))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		return IRQ_NONE;  /* Not our interrupt */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	 * not set, then the adapter didn't send an interrupt */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
	if (unlikely(hw->mac_type >= e1000_82571 &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	             !(icr & E1000_ICR_INT_ASSERTED)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
		return IRQ_NONE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	/* Interrupt Auto-Mask...upon reading ICR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	 * interrupts are masked.  No need for the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	 * IMC write, but it does mean we should
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	 * account for it ASAP. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	if (!adapter->ecdev && likely(hw->mac_type >= e1000_82571))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		atomic_inc(&adapter->irq_sem);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	if (!adapter->ecdev && unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		hw->get_link_status = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
		/* 80003ES2LAN workaround--
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		 * For packet buffer work-around on link down event;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		 * disable receives here in the ISR and
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		 * reset adapter in watchdog
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		if (netif_carrier_ok(netdev) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		    (adapter->hw.mac_type == e1000_80003es2lan)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
			/* disable receives */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
			rctl = E1000_READ_REG(hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
			E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
		/* guard against interrupt when we're going down */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
		if (!test_bit(__E1000_DOWN, &adapter->flags))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4013
	if (adapter->ecdev) {
1325
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  4014
#ifdef CONFIG_E1000_NAPI
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  4015
		int ec_work_done = 0;
16aacb421bd4 merge -c1602 branches/stable-1.4: Fixed e1000 ring bug.
Florian Pose <fp@igh-essen.com>
parents: 1154
diff changeset
  4016
#endif
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4017
		for (i = 0; i < E1000_MAX_INTR; i++)
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
#ifdef CONFIG_E1000_NAPI
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4019
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4020
                            &ec_work_done, 100) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4021
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4022
#else
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4023
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4024
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4025
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4026
				break;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4027
	} else {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4028
#ifdef CONFIG_E1000_NAPI
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		if (unlikely(hw->mac_type < e1000_82571)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
			/* disable interrupts, without the synchronize_irq bit */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
			atomic_inc(&adapter->irq_sem);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
			E1000_WRITE_REG(hw, IMC, ~0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
			E1000_WRITE_FLUSH(hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
		if (likely(netif_rx_schedule_prep(netdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
			adapter->total_tx_bytes = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
			adapter->total_tx_packets = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			adapter->total_rx_bytes = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
			adapter->total_rx_packets = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
			__netif_rx_schedule(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
		} else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
			/* this really should not happen! if it does it is basically a
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
			 * bug, but not a hard error, so enable ints and continue */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
			e1000_irq_enable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
#else
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4046
		/* Writing IMC and IMS is needed for 82547.
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4047
		 * Due to Hub Link bus being occupied, an interrupt
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4048
		 * de-assertion message is not able to be sent.
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4049
		 * When an interrupt assertion message is generated later,
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4050
		 * two messages are re-ordered and sent out.
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4051
		 * That causes APIC to think 82547 is in de-assertion
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4052
		 * state, while 82547 is in assertion state, resulting
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4053
		 * in dead lock. Writing IMC forces 82547 into
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4054
		 * de-assertion state.
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4055
		 */
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4056
		if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) {
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4057
			atomic_inc(&adapter->irq_sem);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4058
			E1000_WRITE_REG(hw, IMC, ~0);
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4059
		}
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4060
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4061
		adapter->total_tx_bytes = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4062
		adapter->total_rx_bytes = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4063
		adapter->total_tx_packets = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4064
		adapter->total_rx_packets = 0;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4065
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4066
		for (i = 0; i < E1000_MAX_INTR; i++)
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4067
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4068
						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4069
				break;
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4070
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		if (likely(adapter->itr_setting & 3))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
			e1000_set_itr(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
			e1000_irq_enable(adapter);
694
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4076
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4077
#endif
54a169382e28 e1000 also supporting PCI MSI interrupts.
Florian Pose <fp@igh-essen.com>
parents: 680
diff changeset
  4078
	}
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	return IRQ_HANDLED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 * e1000_clean - NAPI Rx polling callback
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
e1000_clean(struct net_device *poll_dev, int *budget) // EtherCAT: never called
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
	struct e1000_adapter *adapter;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	int work_to_do = min(*budget, poll_dev->quota);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	int tx_cleaned = 0, work_done = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	/* Must NOT use netdev_priv macro here. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	adapter = poll_dev->priv;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	/* Keep link state information with original netdev */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	if (!netif_carrier_ok(poll_dev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
		goto quit_polling;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	/* e1000_clean is called per-cpu.  This lock protects
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	 * tx_ring[0] from being cleaned by multiple cpus
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	 * simultaneously.  A failure obtaining the lock means
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	 * tx_ring[0] is currently being cleaned anyway. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	if (spin_trylock(&adapter->tx_queue_lock)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		tx_cleaned = e1000_clean_tx_irq(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
		                                &adapter->tx_ring[0]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
		spin_unlock(&adapter->tx_queue_lock);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	                  &work_done, work_to_do);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	*budget -= work_done;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
	poll_dev->quota -= work_done;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	/* If no Tx and not enough Rx work done, exit the polling mode */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	if ((!tx_cleaned && (work_done == 0)) ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	   !netif_running(poll_dev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
quit_polling:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		if (likely(adapter->itr_setting & 3))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
			e1000_set_itr(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
		netif_rx_complete(poll_dev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
		e1000_irq_enable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
		return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	return 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
static boolean_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
e1000_clean_tx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
                   struct e1000_tx_ring *tx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
	struct e1000_tx_desc *tx_desc, *eop_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	unsigned int i, eop;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	unsigned int count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	boolean_t cleaned = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	unsigned int total_tx_bytes=0, total_tx_packets=0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
	i = tx_ring->next_to_clean;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	eop = tx_ring->buffer_info[i].next_to_watch;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
		for (cleaned = FALSE; !cleaned; ) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
			tx_desc = E1000_TX_DESC(*tx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			buffer_info = &tx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
			cleaned = (i == eop);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
			if (cleaned) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
				struct sk_buff *skb = buffer_info->skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
				unsigned int segs = skb_shinfo(skb)->gso_segs;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
				total_tx_packets += segs;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
				total_tx_packets++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
				total_tx_bytes += skb->len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
			tx_desc->upper.data = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			if (unlikely(++i == tx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		eop = tx_ring->buffer_info[i].next_to_watch;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
#define E1000_TX_WEIGHT 64
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
		/* weight of a sort for tx, to avoid endless transmit cleanup */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
		if (count++ == E1000_TX_WEIGHT) break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	tx_ring->next_to_clean = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
#define TX_WAKE_THRESHOLD 32
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	if (!adapter->ecdev && unlikely(cleaned && netif_carrier_ok(netdev) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
		/* Make sure that anybody stopping the queue after this
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
		 * sees the new next_to_clean.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		smp_mb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
		if (netif_queue_stopped(netdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
			netif_wake_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
			++adapter->restart_queue;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
	if (!adapter->ecdev && adapter->detect_tx_hung) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		/* Detect a transmit hang in hardware, this serializes the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		 * check with the clearing of time_stamp and movement of i */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
		adapter->detect_tx_hung = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		if (tx_ring->buffer_info[eop].dma &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		               (adapter->tx_timeout_factor * HZ))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
		    && !(E1000_READ_REG(&adapter->hw, STATUS) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		         E1000_STATUS_TXOFF)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
			/* detected Tx unit hang */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
					"  Tx Queue             <%lu>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
					"  TDH                  <%x>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
					"  TDT                  <%x>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
					"  next_to_use          <%x>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
					"  next_to_clean        <%x>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
					"buffer_info[next_to_clean]\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
					"  time_stamp           <%lx>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
					"  next_to_watch        <%x>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
					"  jiffies              <%lx>\n"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
					"  next_to_watch.status <%x>\n",
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
				(unsigned long)((tx_ring - adapter->tx_ring) /
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
					sizeof(struct e1000_tx_ring)),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
				readl(adapter->hw.hw_addr + tx_ring->tdh),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
				readl(adapter->hw.hw_addr + tx_ring->tdt),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
				tx_ring->next_to_use,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
				tx_ring->next_to_clean,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
				tx_ring->buffer_info[eop].time_stamp,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
				eop,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
				jiffies,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
				eop_desc->upper.fields.status);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
			netif_stop_queue(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	adapter->total_tx_bytes += total_tx_bytes;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	adapter->total_tx_packets += total_tx_packets;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	return cleaned;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
 * e1000_rx_checksum - Receive Checksum Offload for 82543
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * @adapter:     board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * @status_err:  receive descriptor status and error fields
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 * @csum:        receive descriptor csum field
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
 * @sk_buff:     socket buffer with received data
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
e1000_rx_checksum(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
		  uint32_t status_err, uint32_t csum,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
		  struct sk_buff *skb)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	uint16_t status = (uint16_t)status_err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
	uint8_t errors = (uint8_t)(status_err >> 24);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	skb->ip_summed = CHECKSUM_NONE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	/* 82543 or newer only */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	if (unlikely(adapter->hw.mac_type < e1000_82543)) return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	/* Ignore Checksum bit is set */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	/* TCP/UDP checksum error bit is set */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		/* let the stack verify checksum errors */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		adapter->hw_csum_err++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	/* TCP/UDP Checksum has not been calculated */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	if (adapter->hw.mac_type <= e1000_82547_rev_2) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		if (!(status & E1000_RXD_STAT_TCPCS))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
			return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	/* It must be a TCP or UDP packet with a valid checksum */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
		/* TCP checksum is good */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		skb->ip_summed = CHECKSUM_UNNECESSARY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	} else if (adapter->hw.mac_type > e1000_82547_rev_2) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		/* IP fragment with UDP payload */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		/* Hardware complements the payload checksum, so we undo it
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		 * and then put the value in host order for further stack use.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		csum = ntohl(csum ^ 0xFFFF);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		skb->csum = csum;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		skb->ip_summed = CHECKSUM_COMPLETE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	adapter->hw_csum_good++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
static boolean_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
e1000_clean_rx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
                   struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
                   int *work_done, int work_to_do)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
#else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
e1000_clean_rx_irq(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
                   struct e1000_rx_ring *rx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	struct e1000_rx_desc *rx_desc, *next_rxd;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	struct e1000_buffer *buffer_info, *next_buffer;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	unsigned long flags;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	uint32_t length;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	uint8_t last_byte;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	int cleaned_count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
	boolean_t cleaned = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	unsigned int total_rx_bytes=0, total_rx_packets=0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	i = rx_ring->next_to_clean;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	rx_desc = E1000_RX_DESC(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
	buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	while (rx_desc->status & E1000_RXD_STAT_DD) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		struct sk_buff *skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
		u8 status;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
		if (*work_done >= work_to_do)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		(*work_done)++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		status = rx_desc->status;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
		skb = buffer_info->skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
		if (!adapter->ecdev) buffer_info->skb = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		prefetch(skb->data - NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		if (++i == rx_ring->count) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		next_rxd = E1000_RX_DESC(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
		prefetch(next_rxd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		next_buffer = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		cleaned = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		cleaned_count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
		pci_unmap_single(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		                 buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		                 buffer_info->length,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		                 PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		length = le16_to_cpu(rx_desc->length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
			/* All receives must fit into a single buffer */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
			E1000_DBG("%s: Receive packet consumed multiple"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
				  " buffers\n", netdev->name);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
			/* recycle */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
			buffer_info->skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
			goto next_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		if (!adapter->ecdev &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
                unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
			last_byte = *(skb->data + length - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
			if (TBI_ACCEPT(&adapter->hw, status,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
			              rx_desc->errors, length, last_byte)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
				spin_lock_irqsave(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
				e1000_tbi_adjust_stats(&adapter->hw,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
				                       &adapter->stats,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
				                       length, skb->data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
				spin_unlock_irqrestore(&adapter->stats_lock,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
				                       flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
				length--;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
				/* recycle */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
				buffer_info->skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
				goto next_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		/* adjust length to remove Ethernet CRC, this must be
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		 * done after the TBI_ACCEPT workaround above */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
		length -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		/* probably a little skewed due to removing CRC */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
		total_rx_bytes += length;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
		total_rx_packets++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		/* code added for copybreak, this should improve
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
		 * performance for small packets with large amounts
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		 * of reassembly being done in the stack */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
		if (!adapter->ecdev && length < copybreak) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
			struct sk_buff *new_skb =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			if (new_skb) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
				skb_reserve(new_skb, NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
				memcpy(new_skb->data - NET_IP_ALIGN,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
				       skb->data - NET_IP_ALIGN,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
				       length + NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
				/* save the skb in buffer_info as good */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
				buffer_info->skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
				skb = new_skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
			/* else just continue with the old one */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
		/* end copybreak code */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		skb_put(skb, length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		/* Receive Checksum Offload */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		e1000_rx_checksum(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
				  (uint32_t)(status) |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
				  ((uint32_t)(rx_desc->errors) << 24),
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
				  le16_to_cpu(rx_desc->csum), skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
			ecdev_receive(adapter->ecdev, skb->data, length);
1152
30f168c7f74f No need to call e1000 watchdog when frames are received (thanks to O. Zarges).
Florian Pose <fp@igh-essen.com>
parents: 1011
diff changeset
  4415
30f168c7f74f No need to call e1000 watchdog when frames are received (thanks to O. Zarges).
Florian Pose <fp@igh-essen.com>
parents: 1011
diff changeset
  4416
			// No need to detect link status as
30f168c7f74f No need to call e1000 watchdog when frames are received (thanks to O. Zarges).
Florian Pose <fp@igh-essen.com>
parents: 1011
diff changeset
  4417
			// long as frames are received: Reset watchdog.
30f168c7f74f No need to call e1000 watchdog when frames are received (thanks to O. Zarges).
Florian Pose <fp@igh-essen.com>
parents: 1011
diff changeset
  4418
			adapter->ec_watchdog_jiffies = jiffies;
680
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
			skb->protocol = eth_type_trans(skb, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
			if (unlikely(adapter->vlgrp &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
						(status & E1000_RXD_STAT_VP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
				vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
						le16_to_cpu(rx_desc->special) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
						E1000_RXD_SPC_VLAN_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
				netif_receive_skb(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
#else /* CONFIG_E1000_NAPI */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
			if (unlikely(adapter->vlgrp &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
						(status & E1000_RXD_STAT_VP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
				vlan_hwaccel_rx(skb, adapter->vlgrp,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
						le16_to_cpu(rx_desc->special) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
						E1000_RXD_SPC_VLAN_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
				netif_rx(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
#endif /* CONFIG_E1000_NAPI */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		netdev->last_rx = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
next_desc:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		rx_desc->status = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		/* return some buffers to hardware, one at a time is too slow */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
			cleaned_count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
		/* use prefetched values */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
		rx_desc = next_rxd;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
		buffer_info = next_buffer;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
	rx_ring->next_to_clean = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	if (cleaned_count)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	adapter->total_rx_packets += total_rx_packets;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	adapter->total_rx_bytes += total_rx_bytes;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	return cleaned;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
 * @adapter: board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
static boolean_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
                      struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
                      int *work_done, int work_to_do)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
#else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
                      struct e1000_rx_ring *rx_ring)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	struct e1000_buffer *buffer_info, *next_buffer;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	struct e1000_ps_page *ps_page;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	struct e1000_ps_page_dma *ps_page_dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
	struct sk_buff *skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	unsigned int i, j;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	uint32_t length, staterr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	int cleaned_count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
	boolean_t cleaned = FALSE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	unsigned int total_rx_bytes=0, total_rx_packets=0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
	i = rx_ring->next_to_clean;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	while (staterr & E1000_RXD_STAT_DD) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
		ps_page = &rx_ring->ps_page[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		ps_page_dma = &rx_ring->ps_page_dma[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		if (unlikely(*work_done >= work_to_do))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		(*work_done)++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		skb = buffer_info->skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		/* in the packet split case this is header only */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		prefetch(skb->data - NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		if (++i == rx_ring->count) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		prefetch(next_rxd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		next_buffer = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		cleaned = TRUE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		cleaned_count++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		pci_unmap_single(pdev, buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
				 buffer_info->length,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
				 PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			E1000_DBG("%s: Packet Split buffers didn't pick up"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
				  " the full packet\n", netdev->name);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			if (!adapter->ecdev) dev_kfree_skb_irq(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
			goto next_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
			if (!adapter->ecdev) dev_kfree_skb_irq(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
			goto next_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		length = le16_to_cpu(rx_desc->wb.middle.length0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		if (unlikely(!length)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
			E1000_DBG("%s: Last part of the packet spanning"
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
				  " multiple descriptors\n", netdev->name);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
			if (!adapter->ecdev) dev_kfree_skb_irq(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
			goto next_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
		/* Good Receive */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		skb_put(skb, length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		/* this looks ugly, but it seems compiler issues make it
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		   more efficient than reusing j */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		/* page alloc/put takes too long and effects small packet
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		 * throughput, so unsplit small packets and save the alloc/put*/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
		if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			u8 *vaddr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
			/* there is no documentation about how to call
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
			 * kmap_atomic, so we can't hold the mapping
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
			 * very long */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			pci_dma_sync_single_for_cpu(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
				ps_page_dma->ps_page_dma[0],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
				PAGE_SIZE,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
				PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
			vaddr = kmap_atomic(ps_page->ps_page[0],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
			                    KM_SKB_DATA_SOFTIRQ);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
			memcpy(skb->tail, vaddr, l1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
			pci_dma_sync_single_for_device(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
				ps_page_dma->ps_page_dma[0],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
			/* remove the CRC */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			l1 -= 4;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
			skb_put(skb, l1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
			goto copydone;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		} /* if */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		for (j = 0; j < adapter->rx_ps_pages; j++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
			if (!(length= le16_to_cpu(rx_desc->wb.upper.length[j])))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
			pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
					PAGE_SIZE, PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
			ps_page_dma->ps_page_dma[j] = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
			skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
			                   length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
			ps_page->ps_page[j] = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
			skb->len += length;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
			skb->data_len += length;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
			skb->truesize += length;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		/* strip the ethernet crc, problem is we're using pages now so
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
		 * this whole operation can get a little cpu intensive */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		pskb_trim(skb, skb->len - 4);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
copydone:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		total_rx_bytes += skb->len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		total_rx_packets++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		e1000_rx_checksum(adapter, staterr,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
				  le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
		if (likely(rx_desc->wb.upper.header_status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
			adapter->rx_hdr_split++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		if (adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
			ecdev_receive(adapter->ecdev, skb->data, length);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
			skb->protocol = eth_type_trans(skb, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
#ifdef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
			if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
				vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
						le16_to_cpu(rx_desc->wb.middle.vlan) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
						E1000_RXD_SPC_VLAN_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
				netif_receive_skb(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
#else /* CONFIG_E1000_NAPI */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
			if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
				vlan_hwaccel_rx(skb, adapter->vlgrp,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
						le16_to_cpu(rx_desc->wb.middle.vlan) &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
						E1000_RXD_SPC_VLAN_MASK);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
			} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
				netif_rx(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
#endif /* CONFIG_E1000_NAPI */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		netdev->last_rx = jiffies;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
next_desc:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		if (!adapter->ecdev) buffer_info->skb = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		/* return some buffers to hardware, one at a time is too slow */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			cleaned_count = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		/* use prefetched values */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		rx_desc = next_rxd;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		buffer_info = next_buffer;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	rx_ring->next_to_clean = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	if (cleaned_count)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	adapter->total_rx_packets += total_rx_packets;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	adapter->total_rx_bytes += total_rx_bytes;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	return cleaned;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
                       struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		       int cleaned_count)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
	struct e1000_rx_desc *rx_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	struct sk_buff *skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	unsigned int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	i = rx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	while (cleaned_count--) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		skb = buffer_info->skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		if (skb) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
			skb_trim(skb, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
			goto map_skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
		skb = netdev_alloc_skb(netdev, bufsz);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
		if (unlikely(!skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
			/* Better luck next round */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
			adapter->alloc_rx_buff_failed++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		/* Fix for errata 23, can't cross 64kB boundary */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
			struct sk_buff *oldskb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
					     "at %p\n", bufsz, skb->data);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
			/* Try again, without freeing the previous */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
			skb = netdev_alloc_skb(netdev, bufsz);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
			/* Failed allocation, critical failure */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
			if (!skb) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
				dev_kfree_skb(oldskb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
				/* give up */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
				dev_kfree_skb(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
				dev_kfree_skb(oldskb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
				break; /* while !buffer_info->skb */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
			/* Use new allocation */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
			dev_kfree_skb(oldskb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		/* Make buffer alignment 2 beyond a 16 byte boundary
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
		 * this will result in a 16 byte aligned IP header after
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		 * the 14 byte MAC header is removed
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		skb_reserve(skb, NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		buffer_info->skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		buffer_info->length = adapter->rx_buffer_len;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
map_skb:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		buffer_info->dma = pci_map_single(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
						  skb->data,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
						  adapter->rx_buffer_len,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
						  PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		/* Fix for errata 23, can't cross 64kB boundary */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		if (!e1000_check_64k_bound(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
					(void *)(unsigned long)buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
					adapter->rx_buffer_len)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
			DPRINTK(RX_ERR, ERR,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
				"dma align check failed: %u bytes at %p\n",
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
				adapter->rx_buffer_len,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
				(void *)(unsigned long)buffer_info->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
			if (!adapter->ecdev) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
                dev_kfree_skb(skb);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
				buffer_info->skb = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
			pci_unmap_single(pdev, buffer_info->dma,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
					 adapter->rx_buffer_len,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
					 PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
			break; /* while !buffer_info->skb */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		rx_desc = E1000_RX_DESC(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		if (unlikely(++i == rx_ring->count))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
			i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	if (likely(rx_ring->next_to_use != i)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		rx_ring->next_to_use = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		if (unlikely(i-- == 0))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
			i = (rx_ring->count - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
		/* Force memory writes to complete before letting h/w
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		 * know there are new descriptors to fetch.  (Only
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
		 * applicable for weak-ordered memory model archs,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
		 * such as IA-64). */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
		wmb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
 * @adapter: address of board private structure
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
                          struct e1000_rx_ring *rx_ring,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
			  int cleaned_count)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	struct net_device *netdev = adapter->netdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	struct pci_dev *pdev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	union e1000_rx_desc_packet_split *rx_desc;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
	struct e1000_buffer *buffer_info;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	struct e1000_ps_page *ps_page;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	struct e1000_ps_page_dma *ps_page_dma;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	struct sk_buff *skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
	unsigned int i, j;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	i = rx_ring->next_to_use;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	ps_page = &rx_ring->ps_page[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	ps_page_dma = &rx_ring->ps_page_dma[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	while (cleaned_count--) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
			if (j < adapter->rx_ps_pages) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
				if (likely(!ps_page->ps_page[j])) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
					ps_page->ps_page[j] =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
						alloc_page(GFP_ATOMIC);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
					if (unlikely(!ps_page->ps_page[j])) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
						adapter->alloc_rx_buff_failed++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
						goto no_buffers;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
					}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
					ps_page_dma->ps_page_dma[j] =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
						pci_map_page(pdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
							    ps_page->ps_page[j],
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
							    0, PAGE_SIZE,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
							    PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
				/* Refresh the desc even if buffer_addrs didn't
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
				 * change because each write-back erases
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
				 * this info.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
				 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
				rx_desc->read.buffer_addr[j+1] =
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
				     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
			} else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
				rx_desc->read.buffer_addr[j+1] = ~0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
		skb = netdev_alloc_skb(netdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		                       adapter->rx_ps_bsize0 + NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		if (unlikely(!skb)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
			adapter->alloc_rx_buff_failed++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
			break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
		/* Make buffer alignment 2 beyond a 16 byte boundary
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		 * this will result in a 16 byte aligned IP header after
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		 * the 14 byte MAC header is removed
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		skb_reserve(skb, NET_IP_ALIGN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		buffer_info->skb = skb;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		buffer_info->length = adapter->rx_ps_bsize0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
		buffer_info->dma = pci_map_single(pdev, skb->data,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
						  adapter->rx_ps_bsize0,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
						  PCI_DMA_FROMDEVICE);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
		if (unlikely(++i == rx_ring->count)) i = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		buffer_info = &rx_ring->buffer_info[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
		ps_page = &rx_ring->ps_page[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
		ps_page_dma = &rx_ring->ps_page_dma[i];
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
no_buffers:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	if (likely(rx_ring->next_to_use != i)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
		rx_ring->next_to_use = i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
		/* Force memory writes to complete before letting h/w
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		 * know there are new descriptors to fetch.  (Only
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		 * applicable for weak-ordered memory model archs,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		 * such as IA-64). */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
		wmb();
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		/* Hardware increments by 16 bytes, but packet split
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		 * descriptors are 32 bytes...so we increment tail
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
		 * twice as much.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
		 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
		writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
 * @adapter:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
e1000_smartspeed(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	uint16_t phy_status;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	uint16_t phy_ctrl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
	if ((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
	   !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	if (adapter->smartspeed == 0) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
		/* If Master/Slave config fault is asserted twice,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
		 * we assume back-to-back */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
			e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
					    phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
			adapter->smartspeed++;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
			if (!e1000_phy_setup_autoneg(&adapter->hw) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
			   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
				   	       &phy_ctrl)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
					     MII_CR_RESTART_AUTO_NEG);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
				e1000_write_phy_reg(&adapter->hw, PHY_CTRL,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
						    phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
		/* If still no link, perhaps using 2/3 pair cable */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
		e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
		phy_ctrl |= CR_1000T_MS_ENABLE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
		e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
		if (!e1000_phy_setup_autoneg(&adapter->hw) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
		   !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
				     MII_CR_RESTART_AUTO_NEG);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
		adapter->smartspeed = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
 * e1000_ioctl -
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
 * @netdev:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
 * @ifreq:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
 * @cmd:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	switch (cmd) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	case SIOCGMIIPHY:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	case SIOCGMIIREG:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	case SIOCSMIIREG:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		return e1000_mii_ioctl(netdev, ifr, cmd);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		return -EOPNOTSUPP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
 * e1000_mii_ioctl -
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
 * @netdev:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
 * @ifreq:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
 * @cmd:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
 **/
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	struct mii_ioctl_data *data = if_mii(ifr);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
	int retval;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	uint16_t mii_reg;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
	uint16_t spddplx;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	unsigned long flags;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	if (adapter->hw.media_type != e1000_media_type_copper)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
		return -EOPNOTSUPP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
	switch (cmd) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	case SIOCGMIIPHY:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
		data->phy_id = adapter->hw.phy_addr;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	case SIOCGMIIREG:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
		if (adapter->ecdev || !capable(CAP_NET_ADMIN))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
			return -EPERM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
		spin_lock_irqsave(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
		if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
				   &data->val_out)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
			return -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	case SIOCSMIIREG:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		if (adapter->ecdev || !capable(CAP_NET_ADMIN))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
			return -EPERM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		if (data->reg_num & ~(0x1F))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
			return -EFAULT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
		mii_reg = data->val_in;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
		spin_lock_irqsave(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
		if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
					mii_reg)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
			return -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		if (adapter->hw.media_type == e1000_media_type_copper) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
			switch (data->reg_num) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
			case PHY_CTRL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
				if (mii_reg & MII_CR_POWER_DOWN)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
					adapter->hw.autoneg = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
					adapter->hw.autoneg_advertised = 0x2F;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
				} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
					if (mii_reg & 0x40)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
						spddplx = SPEED_1000;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
					else if (mii_reg & 0x2000)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
						spddplx = SPEED_100;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
					else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
						spddplx = SPEED_10;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
					spddplx += (mii_reg & 0x100)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
						   ? DUPLEX_FULL :
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
						   DUPLEX_HALF;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
					retval = e1000_set_spd_dplx(adapter,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
								    spddplx);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
					if (retval) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
						spin_unlock_irqrestore(
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
							&adapter->stats_lock,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
							flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
						return retval;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
					}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
				if (netif_running(adapter->netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
					e1000_reinit_locked(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
				else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
					e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
			case M88E1000_PHY_SPEC_CTRL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
			case M88E1000_EXT_PHY_SPEC_CTRL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
				if (e1000_phy_reset(&adapter->hw)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
					spin_unlock_irqrestore(
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
						&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
					return -EIO;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
				}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
		} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
			switch (data->reg_num) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
			case PHY_CTRL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
				if (mii_reg & MII_CR_POWER_DOWN)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
					break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
				if (netif_running(adapter->netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
					e1000_reinit_locked(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
				else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
					e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
				break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
		return -EOPNOTSUPP;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	return E1000_SUCCESS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
e1000_pci_set_mwi(struct e1000_hw *hw)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	struct e1000_adapter *adapter = hw->back;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
	int ret_val = pci_set_mwi(adapter->pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
	if (ret_val)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
e1000_pci_clear_mwi(struct e1000_hw *hw)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
	struct e1000_adapter *adapter = hw->back;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
	pci_clear_mwi(adapter->pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	struct e1000_adapter *adapter = hw->back;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	pci_read_config_word(adapter->pdev, reg, value);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	struct e1000_adapter *adapter = hw->back;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	pci_write_config_word(adapter->pdev, reg, *value);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
int32_t
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
    struct e1000_adapter *adapter = hw->back;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
    uint16_t cap_offset;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
    if (!cap_offset)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
        return -E1000_ERR_CONFIG;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
    return E1000_SUCCESS;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	outl(value, port);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	uint32_t ctrl, rctl;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	e1000_irq_disable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	adapter->vlgrp = grp;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
	if (grp) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
		/* enable VLAN tag insert/strip */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
		ctrl |= E1000_CTRL_VME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		if (adapter->hw.mac_type != e1000_ich8lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
			/* enable VLAN receive filtering */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
			rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
			rctl |= E1000_RCTL_VFE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
			rctl &= ~E1000_RCTL_CFIEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
			e1000_update_mng_vlan(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
		/* disable VLAN tag insert/strip */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
		ctrl = E1000_READ_REG(&adapter->hw, CTRL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
		ctrl &= ~E1000_CTRL_VME;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
		if (adapter->hw.mac_type != e1000_ich8lan) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
			/* disable VLAN filtering */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
			rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
			rctl &= ~E1000_RCTL_VFE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
			if (adapter->mng_vlan_id !=
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
			    (uint16_t)E1000_MNG_VLAN_NONE) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
				e1000_vlan_rx_kill_vid(netdev,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
				                       adapter->mng_vlan_id);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
			}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
	e1000_irq_enable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
	uint32_t vfta, index;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
	if ((adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
	    (vid == adapter->mng_vlan_id))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	/* add VID to filter table */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
	index = (vid >> 5) & 0x7F;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	vfta |= (1 << (vid & 0x1F));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	e1000_write_vfta(&adapter->hw, index, vfta);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	uint32_t vfta, index;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	e1000_irq_disable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	if (adapter->vlgrp)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
		adapter->vlgrp->vlan_devices[vid] = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	e1000_irq_enable(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
	if ((adapter->hw.mng_cookie.status &
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
	    (vid == adapter->mng_vlan_id)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
		/* release control to f/w */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
		e1000_release_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
	/* remove VID from filter table */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	index = (vid >> 5) & 0x7F;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	vfta &= ~(1 << (vid & 0x1F));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
	e1000_write_vfta(&adapter->hw, index, vfta);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
e1000_restore_vlan(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	if (adapter->vlgrp) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
		uint16_t vid;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
			if (!adapter->vlgrp->vlan_devices[vid])
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
				continue;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	adapter->hw.autoneg = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
	/* Fiber NICs only allow 1000 gbps Full duplex */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	if ((adapter->hw.media_type == e1000_media_type_fiber) &&
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
		return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
	switch (spddplx) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
	case SPEED_10 + DUPLEX_HALF:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
		adapter->hw.forced_speed_duplex = e1000_10_half;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	case SPEED_10 + DUPLEX_FULL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		adapter->hw.forced_speed_duplex = e1000_10_full;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
	case SPEED_100 + DUPLEX_HALF:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
		adapter->hw.forced_speed_duplex = e1000_100_half;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	case SPEED_100 + DUPLEX_FULL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
		adapter->hw.forced_speed_duplex = e1000_100_full;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
	case SPEED_1000 + DUPLEX_FULL:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
		adapter->hw.autoneg = 1;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
		break;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	default:
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
		return -EINVAL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
/* Save/restore 16 or 64 dwords of PCI config space depending on which
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
 * bus we're on (PCI(X) vs. PCI-E)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
#define PCIE_CONFIG_SPACE_LEN 256
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
#define PCI_CONFIG_SPACE_LEN 64
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
e1000_pci_save_state(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	struct pci_dev *dev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	int size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
	if (adapter->hw.mac_type >= e1000_82571)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
		size = PCIE_CONFIG_SPACE_LEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
		size = PCI_CONFIG_SPACE_LEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
	WARN_ON(adapter->config_space != NULL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	adapter->config_space = kmalloc(size, GFP_KERNEL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	if (!adapter->config_space) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
		DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
		return -ENOMEM;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	for (i = 0; i < (size / 4); i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
		pci_read_config_dword(dev, i * 4, &adapter->config_space[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
e1000_pci_restore_state(struct e1000_adapter *adapter)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	struct pci_dev *dev = adapter->pdev;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	int size;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	int i;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
	if (adapter->config_space == NULL)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
		return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	if (adapter->hw.mac_type >= e1000_82571)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
		size = PCIE_CONFIG_SPACE_LEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	else
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
		size = PCI_CONFIG_SPACE_LEN;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	for (i = 0; i < (size / 4); i++)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
		pci_write_config_dword(dev, i * 4, adapter->config_space[i]);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	kfree(adapter->config_space);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
	adapter->config_space = NULL;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
#endif /* CONFIG_PM */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
e1000_suspend(struct pci_dev *pdev, pm_message_t state)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
	uint32_t ctrl, ctrl_ext, rctl, status;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	uint32_t wufc = adapter->wol;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
	int retval = 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
		return -EBUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	netif_device_detach(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	if (netif_running(netdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
		e1000_down(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
	/* Implement our own version of pci_save_state(pdev) because pci-
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
	 * express adapters have 256-byte config spaces. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
	retval = e1000_pci_save_state(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
	if (retval)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
		return retval;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
	status = E1000_READ_REG(&adapter->hw, STATUS);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
	if (status & E1000_STATUS_LU)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
		wufc &= ~E1000_WUFC_LNKC;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
	if (wufc) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
		e1000_setup_rctl(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
		e1000_set_multi(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
		/* turn on all-multi mode if wake on multicast is enabled */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
		if (wufc & E1000_WUFC_MC) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
			rctl = E1000_READ_REG(&adapter->hw, RCTL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
			rctl |= E1000_RCTL_MPE;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
		if (adapter->hw.mac_type >= e1000_82540) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
			ctrl = E1000_READ_REG(&adapter->hw, CTRL);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
			/* advertise wake from D3Cold */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
			#define E1000_CTRL_ADVD3WUC 0x00100000
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
			/* phy power management enable */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
			ctrl |= E1000_CTRL_ADVD3WUC |
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
				E1000_CTRL_EN_PHY_PWR_MGMT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
			E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
		if (adapter->hw.media_type == e1000_media_type_fiber ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
		   adapter->hw.media_type == e1000_media_type_internal_serdes) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
			/* keep the laser running in D3 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
			ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
			E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		/* Allow time for pending master requests to run */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
		e1000_disable_pciex_master(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
		E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
		E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
		pci_enable_wake(pdev, PCI_D3hot, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
		pci_enable_wake(pdev, PCI_D3cold, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	} else {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
		E1000_WRITE_REG(&adapter->hw, WUC, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
		E1000_WRITE_REG(&adapter->hw, WUFC, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
		pci_enable_wake(pdev, PCI_D3hot, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
		pci_enable_wake(pdev, PCI_D3cold, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
	e1000_release_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
	/* make sure adapter isn't asleep if manageability is enabled */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
	if (adapter->en_mng_pt) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
		pci_enable_wake(pdev, PCI_D3hot, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
		pci_enable_wake(pdev, PCI_D3cold, 1);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	if (adapter->hw.phy_type == e1000_phy_igp_3)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
		e1000_phy_powerdown_workaround(&adapter->hw);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	if (netif_running(netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
		e1000_free_irq(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
	 * would have already happened in close and is redundant. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
	e1000_release_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
	pci_disable_device(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
#ifdef CONFIG_PM
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
static int
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
e1000_resume(struct pci_dev *pdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	uint32_t err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	if (adapter->ecdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		return -EBUSY;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	pci_set_power_state(pdev, PCI_D0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
	e1000_pci_restore_state(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	if ((err = pci_enable_device(pdev))) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
		return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
	pci_set_master(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
	pci_enable_wake(pdev, PCI_D3hot, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
	pci_enable_wake(pdev, PCI_D3cold, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
	if (netif_running(netdev) && (err = e1000_request_irq(adapter)))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
		return err;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	e1000_power_up_phy(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
	e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	e1000_init_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	if (netif_running(netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
		e1000_up(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	if (!adapter->ecdev) netif_device_attach(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	/* If the controller is 82573 and f/w is AMT, do not set
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	 * DRV_LOAD until the interface is up.  For all other cases,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
	 * let the f/w know that the h/w is now under the control
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	 * of the driver. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
	if (adapter->hw.mac_type != e1000_82573 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	    !e1000_check_mng_mode(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
		e1000_get_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
	return 0;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
static void e1000_shutdown(struct pci_dev *pdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
	e1000_suspend(pdev, PMSG_SUSPEND);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
#ifdef CONFIG_NET_POLL_CONTROLLER
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
/*
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
 * Polling 'interrupt' - used by things like netconsole to send skbs
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
 * without having to re-enable interrupts. It's not called while
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
 * the interrupt routine is executing.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
static void
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
e1000_netpoll(struct net_device *netdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
	struct e1000_adapter *adapter = netdev_priv(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	disable_irq(adapter->pdev->irq);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
	e1000_intr(adapter->pdev->irq, netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
	e1000_clean_tx_irq(adapter, adapter->tx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
#ifndef CONFIG_E1000_NAPI
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
	adapter->clean_rx(adapter, adapter->rx_ring);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	enable_irq(adapter->pdev->irq);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
#endif
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
 * e1000_io_error_detected - called when PCI error is detected
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
 * @pdev: Pointer to PCI device
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
 * @state: The current pci conneection state
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
 * This function is called after a PCI bus error affecting
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
 * this device has been detected.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
	struct e1000_adapter *adapter = netdev->priv;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
	netif_device_detach(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
	if (netif_running(netdev))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
		e1000_down(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
	pci_disable_device(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
	/* Request a slot slot reset. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
	return PCI_ERS_RESULT_NEED_RESET;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
 * e1000_io_slot_reset - called after the pci bus has been reset.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
 * @pdev: Pointer to PCI device
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
 * Restart the card from scratch, as if from a cold-boot. Implementation
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
 * resembles the first-half of the e1000_resume routine.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
	struct e1000_adapter *adapter = netdev->priv;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
	if (pci_enable_device(pdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
		return PCI_ERS_RESULT_DISCONNECT;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	pci_set_master(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
	pci_enable_wake(pdev, PCI_D3hot, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	pci_enable_wake(pdev, PCI_D3cold, 0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	e1000_reset(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	E1000_WRITE_REG(&adapter->hw, WUS, ~0);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	return PCI_ERS_RESULT_RECOVERED;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
/**
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
 * e1000_io_resume - called when traffic can start flowing again.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
 * @pdev: Pointer to PCI device
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
 *
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
 * This callback is called when the error recovery driver tells us that
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
 * its OK to resume normal operation. Implementation resembles the
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
 * second-half of the e1000_resume routine.
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
 */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
static void e1000_io_resume(struct pci_dev *pdev)
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
{
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	struct net_device *netdev = pci_get_drvdata(pdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	struct e1000_adapter *adapter = netdev->priv;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	e1000_init_manageability(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	if (netif_running(netdev)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		if (e1000_up(adapter)) {
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
			printk("e1000: can't bring device back up after reset\n");
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
			return;
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
		}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
	}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
	netif_device_attach(netdev);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
	/* If the controller is 82573 and f/w is AMT, do not set
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
	 * DRV_LOAD until the interface is up.  For all other cases,
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
	 * let the f/w know that the h/w is now under the control
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
	 * of the driver. */
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
	if (adapter->hw.mac_type != e1000_82573 ||
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
	    !e1000_check_mng_mode(&adapter->hw))
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
		e1000_get_hw_control(adapter);
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
}
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
48c2dbc12bde Added e1000 driver for 2.6.20.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
/* e1000_main.c */