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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2584
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
  vim: noexpandtab
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include "e1000-3.8-ethercat.h"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <net/ip6_checksum.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/io.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/prefetch.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/bitops.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/if_vlan.h>
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
char e1000_driver_name[] = "ec_e1000";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#define DRV_VERSION "7.3.21-k8-NAPI"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
const char e1000_driver_version[] = DRV_VERSION;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
/* e1000_pci_tbl - PCI Device ID Table
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
 * Last entry must be all 0s
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
 * Macro expands to...
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	INTEL_E1000_ETHERNET_DEVICE(0x2E6E),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	/* required last entry */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	{0,}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
// do not auto-load driver
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
int e1000_up(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
void e1000_down(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
void e1000_reinit_locked(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
void e1000_reset(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
                             struct e1000_tx_ring *txdr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
                             struct e1000_rx_ring *rxdr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
                             struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
                             struct e1000_rx_ring *rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
void e1000_update_stats(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
static int e1000_init_module(void);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
static void e1000_exit_module(void);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
static void e1000_remove(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static int e1000_alloc_queues(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
static int e1000_sw_init(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
static int e1000_open(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
static int e1000_close(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
static void e1000_configure_tx(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
static void e1000_configure_rx(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
static void e1000_setup_rctl(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
                                struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
                                struct e1000_rx_ring *rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
static void e1000_set_rx_mode(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
static void e1000_update_phy_info_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
static void e1000_watchdog(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
				    struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
static int e1000_set_mac(struct net_device *netdev, void *p);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
void ec_poll(struct net_device *);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static irqreturn_t e1000_intr(int irq, void *data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
			       struct e1000_tx_ring *tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
static int e1000_clean(struct napi_struct *napi, int budget);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
			       struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			       int *work_done, int work_to_do);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
				     struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
				     int *work_done, int work_to_do);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
				   struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
				   int cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
					 struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
					 int cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
			   int cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
static void e1000_tx_timeout(struct net_device *dev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
static void e1000_reset_task(struct work_struct *work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
static void e1000_smartspeed(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
                                       struct sk_buff *skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
static bool e1000_vlan_used(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000_vlan_mode(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
			    netdev_features_t features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
				     bool filter_on);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
static void e1000_restore_vlan(struct e1000_adapter *adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
static int e1000_resume(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
static void e1000_shutdown(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
/* for netdump / net console */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
static void e1000_netpoll (struct net_device *netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
#define COPYBREAK_DEFAULT 256
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
module_param(copybreak, uint, 0644);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
MODULE_PARM_DESC(copybreak,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	"Maximum size of packet that is copied to a new buffer on receive");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
                     pci_channel_state_t state);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
static void e1000_io_resume(struct pci_dev *pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
static const struct pci_error_handlers e1000_err_handler = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	.error_detected = e1000_io_error_detected,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	.slot_reset = e1000_io_slot_reset,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	.resume = e1000_io_resume,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
static struct pci_driver e1000_driver = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	.name     = e1000_driver_name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	.id_table = e1000_pci_tbl,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	.probe    = e1000_probe,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	.remove   = e1000_remove,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	/* Power Management Hooks */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	.suspend  = e1000_suspend,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	.resume   = e1000_resume,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	.shutdown = e1000_shutdown,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	.err_handler = &e1000_err_handler
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
MODULE_LICENSE("GPL");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
MODULE_VERSION(DRV_VERSION);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
static int debug = -1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
module_param(debug, int, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
 * e1000_get_hw_dev - return device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
 * used by hardware layer to print debugging information
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
struct net_device *e1000_get_hw_dev(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	return adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
 * e1000_init_module - Driver Registration Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
 * e1000_init_module is the first routine called when the driver is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
 * loaded. All it does is register with the PCI subsystem.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
static int __init e1000_init_module(void)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	int ret;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	pr_info("%s - version %s\n", e1000_driver_string, e1000_driver_version);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	pr_info("%s\n", e1000_copyright);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	ret = pci_register_driver(&e1000_driver);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	if (copybreak != COPYBREAK_DEFAULT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
		if (copybreak == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
			pr_info("copybreak disabled\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
			pr_info("copybreak enabled for "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
				   "packets <= %u bytes\n", copybreak);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	return ret;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
module_init(e1000_init_module);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
 * e1000_exit_module - Driver Exit Cleanup Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
 * e1000_exit_module is called just before the driver is removed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
 * from memory.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
static void __exit e1000_exit_module(void)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	pci_unregister_driver(&e1000_driver);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
module_exit(e1000_exit_module);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
static int e1000_request_irq(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	irq_handler_t handler = e1000_intr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	int irq_flags = IRQF_SHARED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	                  netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		e_err(probe, "Unable to allocate interrupt Error: %d\n", err);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
static void e1000_free_irq(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	free_irq(adapter->pdev->irq, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
 * e1000_irq_disable - Mask off interrupt generation on the NIC
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
static void e1000_irq_disable(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	ew32(IMC, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	synchronize_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 * e1000_irq_enable - Enable default interrupt generation settings
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
static void e1000_irq_enable(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	ew32(IMS, IMS_ENABLE_MASK);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	u16 vid = hw->mng_cookie.vlan_id;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
	u16 old_vid = adapter->mng_vlan_id;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
	if (!test_bit(vid, adapter->active_vlans)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
		if (hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		    E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
			e1000_vlan_rx_add_vid(netdev, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
			adapter->mng_vlan_id = vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		    (vid != old_vid) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		    !test_bit(old_vid, adapter->active_vlans))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
			e1000_vlan_rx_kill_vid(netdev, old_vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		adapter->mng_vlan_id = vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
static void e1000_init_manageability(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	if (adapter->en_mng_pt) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
		u32 manc = er32(MANC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		/* disable hardware interception of ARP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
		manc &= ~(E1000_MANC_ARP_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		ew32(MANC, manc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
static void e1000_release_manageability(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	if (adapter->en_mng_pt) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		u32 manc = er32(MANC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		/* re-enable hardware interception of ARP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		manc |= E1000_MANC_ARP_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		ew32(MANC, manc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 * e1000_configure - configure the hardware for RX and TX
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
 * @adapter = private board structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
static void e1000_configure(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	e1000_set_rx_mode(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	e1000_restore_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	e1000_configure_tx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	e1000_setup_rctl(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	e1000_configure_rx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	/* call E1000_DESC_UNUSED which always leaves
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	 * at least 1 descriptor unused to make sure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	 * next_to_use != next_to_clean */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	for (i = 0; i < adapter->num_rx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			/* fill rx ring completely! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			adapter->alloc_rx_buf(adapter, ring, ring->count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
			/* this one leaves the last ring element unallocated! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
			adapter->alloc_rx_buf(adapter, ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
					E1000_DESC_UNUSED(ring));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
int e1000_up(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	/* hardware has been reset, we need to reload some things */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	e1000_configure(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	clear_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
		napi_enable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		netif_wake_queue(adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
		/* fire a link change interrupt to start the watchdog */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
		ew32(ICS, E1000_ICS_LSC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
 * e1000_power_up_phy - restore link in case the phy was powered down
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
 * The phy may be powered down to save power and turn off link when the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 * driver is unloaded and wake on lan is not enabled (among others)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
 * *** this routine MUST be followed by a call to e1000_reset ***
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
void e1000_power_up_phy(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	u16 mii_reg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	/* Just clear the power down bit to wake the phy back up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		/* according to the manual, the phy will retain its
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		 * settings across a power-down/up cycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		mii_reg &= ~MII_CR_POWER_DOWN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
static void e1000_power_down_phy(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	/* Power down the PHY so no link is implied when interface is down *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	 * The PHY cannot be powered down if any of the following is true *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	 * (a) WoL is enabled
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	 * (b) AMT is active
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	 * (c) SoL/IDER session is active */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	   hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		u16 mii_reg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		case e1000_82540:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		case e1000_82545:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		case e1000_82545_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		case e1000_ce4100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
				goto out;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
			goto out;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		mii_reg |= MII_CR_POWER_DOWN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
out:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
static void e1000_down_and_stop(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	set_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* Only kill reset task if adapter is not resetting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	if (!test_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		cancel_work_sync(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		cancel_delayed_work_sync(&adapter->watchdog_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		cancel_delayed_work_sync(&adapter->phy_info_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		cancel_delayed_work_sync(&adapter->fifo_stall_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
void e1000_down(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	u32 rctl, tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	/* disable receives in the hardware */	
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		/* flush and sleep below */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
		netif_tx_disable(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	/* disable transmits in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	tctl &= ~E1000_TCTL_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	/* flush both disables and wait for them to finish */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	msleep(10);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
		napi_disable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	 * Setting DOWN must be after irq_disable to prevent
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	 * a screaming interrupt.  Setting DOWN also prevents
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	 * tasks from rescheduling.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	e1000_down_and_stop(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	adapter->link_speed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	adapter->link_duplex = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	e1000_clean_all_tx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	e1000_clean_all_rx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
static void e1000_reinit_safe(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
void e1000_reinit_locked(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	/* if rtnl_lock is not held the call path is bogus */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	ASSERT_RTNL();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	WARN_ON(in_interrupt());
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
void e1000_reset(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	bool legacy_pba_adjust = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	u16 hwm;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	/* Repartition Pba for greater than 9k mtu
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	 * To take effect CTRL.RST is required.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	case e1000_82543:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	case e1000_82540:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		legacy_pba_adjust = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		pba = E1000_PBA_48K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	case e1000_82545:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	case e1000_82545_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	case e1000_ce4100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		pba = E1000_PBA_48K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		legacy_pba_adjust = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		pba = E1000_PBA_30K;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	case e1000_undefined:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	case e1000_num_macs:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	if (legacy_pba_adjust) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		if (hw->max_frame_size > E1000_RXBUFFER_8192)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
			pba -= 8; /* allocate more FIFO for Tx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		if (hw->mac_type == e1000_82547) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
			adapter->tx_fifo_head = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
			adapter->tx_fifo_size =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
			atomic_set(&adapter->tx_fifo_stall, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		/* adjust PBA for jumbo frames */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		ew32(PBA, pba);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		/* To maintain wire speed transmits, the Tx FIFO should be
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		 * large enough to accommodate two full transmit packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		 * the Rx FIFO should be large enough to accommodate at least
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		 * one full receive packet and is similarly rounded up and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		 * expressed in KB. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		pba = er32(PBA);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		/* upper 16 bits has Tx packet buffer allocation size in KB */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
		tx_space = pba >> 16;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		/* lower 16 bits has Rx packet buffer allocation size in KB */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		pba &= 0xffff;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
		 * the tx fifo also stores 16 bytes of information about the tx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		 * but don't include ethernet FCS because hardware appends it
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		min_tx_space = (hw->max_frame_size +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		                sizeof(struct e1000_tx_desc) -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
		                ETH_FCS_LEN) * 2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		min_tx_space = ALIGN(min_tx_space, 1024);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		min_tx_space >>= 10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		/* software strips receive CRC, so leave room for it */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		min_rx_space = hw->max_frame_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
		min_rx_space = ALIGN(min_rx_space, 1024);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		min_rx_space >>= 10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		/* If current Tx allocation is less than the min Tx FIFO size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		 * and the min Tx FIFO size is less than the current Rx FIFO
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		 * allocation, take space away from current Rx allocation */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		if (tx_space < min_tx_space &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		    ((min_tx_space - tx_space) < pba)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			pba = pba - (min_tx_space - tx_space);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
			/* PCI/PCIx hardware has PBA alignment constraints */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
			switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			case e1000_82545 ... e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
				pba &= ~(E1000_PBA_8K - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
			default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			/* if short on rx space, rx wins and must trump tx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			 * adjustment or use Early Receive if available */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			if (pba < min_rx_space)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
				pba = min_rx_space;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	ew32(PBA, pba);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	 * flow control settings:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	 * The high water mark must be low enough to fit one full frame
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	 * (or the size used for early receive) above it in the Rx FIFO.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	 * Set it to the lower of:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	 * - 90% of the Rx FIFO size, and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * - the full Rx FIFO size minus the early receive size (for parts
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * - the full Rx FIFO size minus one full frame
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	hwm = min(((pba << 10) * 9 / 10),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		  ((pba << 10) - hw->max_frame_size));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	hw->fc_low_water = hw->fc_high_water - 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	hw->fc_send_xon = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	hw->fc = hw->original_fc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	/* Allow time for pending master requests to run */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	e1000_reset_hw(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	if (hw->mac_type >= e1000_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		ew32(WUC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	if (e1000_init_hw(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		e_dev_err("Hardware Error\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	if (hw->mac_type >= e1000_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	    hw->autoneg == 1 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		u32 ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		/* clear phy power management bit if we are in gig only mode,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		 * which if enabled will attempt negotiation to 100Mb, which
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		 * can cause a loss of link at power off or driver unload */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		ctrl &= ~E1000_CTRL_SWDPIN3;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
		ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	e1000_reset_adaptive(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	e1000_phy_get_info(hw, &adapter->phy_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
/* Dump the eeprom for users having checksum issues */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	struct ethtool_eeprom eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	const struct ethtool_ops *ops = netdev->ethtool_ops;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	u8 *data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	u16 csum_old, csum_new = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	eeprom.len = ops->get_eeprom_len(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	eeprom.offset = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	data = kmalloc(eeprom.len, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	if (!data)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	ops->get_eeprom(netdev, &eeprom, data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		csum_new += data[i] + (data[i + 1] << 8);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
	csum_new = EEPROM_SUM - csum_new;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
	pr_err("/*********************/\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	pr_err("Current EEPROM Checksum : 0x%04x\n", csum_old);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
	pr_err("Calculated              : 0x%04x\n", csum_new);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
	pr_err("Offset    Values\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	pr_err("========  ======\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	pr_err("Include this output when contacting your support provider.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	pr_err("This is not a software error! Something bad happened to\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	pr_err("your hardware or EEPROM image. Ignoring this problem could\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	pr_err("result in further problems, possibly loss of data,\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	pr_err("corruption or system hangs!\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
	pr_err("The MAC Address will be reset to 00:00:00:00:00:00,\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	pr_err("which is invalid and requires you to set the proper MAC\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	pr_err("address manually before continuing to enable this network\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	pr_err("device. Please inspect the EEPROM dump and report the\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	pr_err("issue to your hardware vendor or Intel Customer Support.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	pr_err("/*********************/\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
	kfree(data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
 * Return true if an adapter needs ioport resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
static int e1000_is_need_ioport(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	switch (pdev->device) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	case E1000_DEV_ID_82540EM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	case E1000_DEV_ID_82540EM_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	case E1000_DEV_ID_82540EP:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	case E1000_DEV_ID_82540EP_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	case E1000_DEV_ID_82540EP_LP:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	case E1000_DEV_ID_82541EI:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	case E1000_DEV_ID_82541EI_MOBILE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	case E1000_DEV_ID_82541ER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
	case E1000_DEV_ID_82541ER_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
	case E1000_DEV_ID_82541GI:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
	case E1000_DEV_ID_82541GI_LF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	case E1000_DEV_ID_82541GI_MOBILE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	case E1000_DEV_ID_82544EI_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	case E1000_DEV_ID_82544EI_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	case E1000_DEV_ID_82544GC_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	case E1000_DEV_ID_82544GC_LOM:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	case E1000_DEV_ID_82545EM_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	case E1000_DEV_ID_82545EM_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	case E1000_DEV_ID_82546EB_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	case E1000_DEV_ID_82546EB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
static netdev_features_t e1000_fix_features(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	 * Since there is no support for separate rx/tx vlan accel
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
	 * enable/disable make sure tx flag is always in same state as rx.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	if (features & NETIF_F_HW_VLAN_RX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		features |= NETIF_F_HW_VLAN_TX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		features &= ~NETIF_F_HW_VLAN_TX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	return features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
static int e1000_set_features(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	netdev_features_t changed = features ^ netdev->features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (changed & NETIF_F_HW_VLAN_RX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		e1000_vlan_mode(netdev, features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	netdev->features = features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
static const struct net_device_ops e1000_netdev_ops = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	.ndo_open		= e1000_open,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	.ndo_stop		= e1000_close,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	.ndo_start_xmit		= e1000_xmit_frame,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	.ndo_get_stats		= e1000_get_stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	.ndo_set_rx_mode	= e1000_set_rx_mode,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	.ndo_set_mac_address	= e1000_set_mac,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	.ndo_tx_timeout		= e1000_tx_timeout,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	.ndo_change_mtu		= e1000_change_mtu,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	.ndo_do_ioctl		= e1000_ioctl,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	.ndo_validate_addr	= eth_validate_addr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	.ndo_poll_controller	= e1000_netpoll,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	.ndo_fix_features	= e1000_fix_features,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	.ndo_set_features	= e1000_set_features,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
 * e1000_init_hw_struct - initialize members of hw struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
 * @adapter: board private struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
 * @hw: structure used by e1000_hw.c
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
 * Factors out initialization of the e1000_hw struct to its own function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
 * that can be called very early at init (just after struct allocation).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
 * Fields are initialized based on PCI device information and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
 * OS network device settings (MTU size).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
 * Returns negative error codes if MAC type setup fails.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
static int e1000_init_hw_struct(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
				struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	/* PCI config space info */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	hw->vendor_id = pdev->vendor;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	hw->device_id = pdev->device;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	hw->subsystem_id = pdev->subsystem_device;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	hw->revision_id = pdev->revision;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	hw->max_frame_size = adapter->netdev->mtu +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	/* identify the MAC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	if (e1000_set_mac_type(hw)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		e_err(probe, "Unknown MAC Type\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	case e1000_82541:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	case e1000_82547:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	case e1000_82541_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	case e1000_82547_rev_2:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		hw->phy_init_script = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	e1000_set_media_type(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	e1000_get_bus_info(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	hw->wait_autoneg_complete = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	hw->tbi_compatibility_en = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	hw->adaptive_ifs = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	/* Copper options */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		hw->mdix = AUTO_ALL_MODES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		hw->disable_polarity_correction = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		hw->master_slave = E1000_MASTER_SLAVE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
 * e1000_probe - Device Initialization Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
 * @ent: entry in e1000_pci_tbl
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
 * e1000_probe initializes an adapter identified by a pci_dev structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
 * The OS initialization, configuring of the adapter private structure,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
 * and a hardware reset occur.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	struct net_device *netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	struct e1000_adapter *adapter;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	struct e1000_hw *hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	static int cards_found = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	int i, err, pci_using_dac;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	u16 eeprom_data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	u16 tmp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	int bars, need_ioport;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	/* do not allocate ioport bars when not needed */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	need_ioport = e1000_is_need_ioport(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	if (need_ioport) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		goto err_pci_reg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	err = pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		goto err_alloc_etherdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	err = -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	if (!netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		goto err_alloc_etherdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	SET_NETDEV_DEV(netdev, &pdev->dev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	pci_set_drvdata(pdev, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	adapter->netdev = netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	adapter->pdev = pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	adapter->bars = bars;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	adapter->need_ioport = need_ioport;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	hw->back = adapter;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	err = -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	if (!hw->hw_addr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		goto err_ioremap;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	if (adapter->need_ioport) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		for (i = BAR_1; i <= BAR_5; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			if (pci_resource_len(pdev, i) == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
				continue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
				hw->io_base = pci_resource_start(pdev, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	/* make ready for any if (hw->...) below */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	err = e1000_init_hw_struct(adapter, hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		goto err_sw_init;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	 * there is a workaround being applied below that limits
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	 * 64-bit DMA addresses to 64-bit hardware.  There are some
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	 * 32-bit adapters that Tx hang when given 64-bit DMA addresses
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	pci_using_dac = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	if ((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		 * according to DMA-API-HOWTO, coherent calls will always
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		 * succeed if the set call did
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		pci_using_dac = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
			pr_err("No usable DMA config, aborting\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
			goto err_dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	netdev->netdev_ops = &e1000_netdev_ops;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	e1000_set_ethtool_ops(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	netdev->watchdog_timeo = 5 * HZ;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	adapter->bd_number = cards_found;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	/* setup the private structure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	err = e1000_sw_init(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		goto err_sw_init;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	err = -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	if (hw->mac_type == e1000_ce4100) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		hw->ce4100_gbe_mdio_base_virt =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
					ioremap(pci_resource_start(pdev, BAR_1),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		                                pci_resource_len(pdev, BAR_1));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		if (!hw->ce4100_gbe_mdio_base_virt)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
			goto err_mdio_ioremap;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		netdev->hw_features = NETIF_F_SG |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
				   NETIF_F_HW_CSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
				   NETIF_F_HW_VLAN_RX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		netdev->features = NETIF_F_HW_VLAN_TX |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
				   NETIF_F_HW_VLAN_FILTER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	if ((hw->mac_type >= e1000_82544) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	   (hw->mac_type != e1000_82547))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		netdev->hw_features |= NETIF_F_TSO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	netdev->priv_flags |= IFF_SUPP_NOFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	netdev->features |= netdev->hw_features;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	netdev->hw_features |= (NETIF_F_RXCSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
				NETIF_F_RXALL |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
				NETIF_F_RXFCS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	if (pci_using_dac) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		netdev->features |= NETIF_F_HIGHDMA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		netdev->vlan_features |= NETIF_F_HIGHDMA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	netdev->vlan_features |= (NETIF_F_TSO |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
				  NETIF_F_HW_CSUM |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				  NETIF_F_SG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	netdev->priv_flags |= IFF_UNICAST_FLT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	/* initialize eeprom parameters */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	if (e1000_init_eeprom_params(hw)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		e_err(probe, "EEPROM initialization failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		goto err_eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	/* before reading the EEPROM, reset the controller to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	 * put the device in a known good starting state */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	e1000_reset_hw(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	/* make sure the EEPROM is good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	if (e1000_validate_eeprom_checksum(hw) < 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		e_err(probe, "The EEPROM Checksum Is Not Valid\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		e1000_dump_eeprom(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		 * set MAC address to all zeroes to invalidate and temporary
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		 * disable this device for the user. This blocks regular
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 * traffic while still permitting ethtool ioctls from reaching
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * the hardware as well as allowing the user to run the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 * interface after manually setting a hw addr using
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		 * `ip set address`
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		memset(hw->mac_addr, 0, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		/* copy the MAC address out of the EEPROM */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		if (e1000_read_mac_addr(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			e_err(probe, "EEPROM Read Error\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	/* don't block initalization here due to bad MAC address */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	if (!is_valid_ether_addr(netdev->perm_addr))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		e_err(probe, "Invalid MAC Address\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	INIT_DELAYED_WORK(&adapter->fifo_stall_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			  e1000_82547_tx_fifo_stall_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	INIT_DELAYED_WORK(&adapter->phy_info_task, e1000_update_phy_info_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
	e1000_check_options(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	/* Initial Wake on LAN setting
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
	 * If APM wake is enabled in the EEPROM,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	 * enable the ACPI Magic Packet filter
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	case e1000_82543:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	case e1000_82546:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	case e1000_82546_rev_3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
			e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		/* Fall Through */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		e1000_read_eeprom(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	if (eeprom_data & eeprom_apme_mask)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		adapter->eeprom_wol |= E1000_WUFC_MAG;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	/* now that we have the eeprom settings, apply the special cases
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	 * where the eeprom may be wrong or the board simply won't support
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	 * wake on lan on a particular port */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	switch (pdev->device) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	case E1000_DEV_ID_82546GB_PCIE:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	case E1000_DEV_ID_82546EB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	case E1000_DEV_ID_82546GB_FIBER:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		/* Wake events only supported on port A for dual fiber
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		 * regardless of eeprom setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		/* if quad port adapter, disable WoL on all but port A */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		if (global_quad_port_a != 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
			adapter->eeprom_wol = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
			adapter->quad_port_a = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		/* Reset for multiple quad port adapters */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		if (++global_quad_port_a == 4)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
			global_quad_port_a = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	/* initialize the wol settings based on the eeprom settings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	adapter->wol = adapter->eeprom_wol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	/* Auto detect PHY address */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	if (hw->mac_type == e1000_ce4100) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		for (i = 0; i < 32; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
			hw->phy_addr = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			e1000_read_phy_reg(hw, PHY_ID2, &tmp);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			if (tmp == 0 || tmp == 0xFF) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
				if (i == 31)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
					goto err_eeprom;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
				continue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
			} else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	/* reset the hardware with the new settings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
 	// offer device to EtherCAT master module
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		err = ecdev_open(adapter->ecdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
			ecdev_withdraw(adapter->ecdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
			goto err_register;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		strcpy(netdev->name, "eth%d");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		err = register_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
			goto err_register;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	e1000_vlan_filter_on_off(adapter, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	/* print bus type/speed/width info */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	       ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	       ((hw->bus_speed == e1000_bus_speed_133) ? 133 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		(hw->bus_speed == e1000_bus_speed_120) ? 120 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		(hw->bus_speed == e1000_bus_speed_100) ? 100 :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		(hw->bus_speed == e1000_bus_speed_66) ? 66 : 33),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	       ((hw->bus_width == e1000_bus_width_64) ? 64 : 32),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	       netdev->dev_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		/* carrier off reporting is important to ethtool even BEFORE open */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	e_info(probe, "Intel(R) PRO/1000 Network Connection\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	cards_found++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
err_register:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
err_eeprom:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	e1000_phy_hw_reset(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	if (hw->flash_address)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		iounmap(hw->flash_address);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	kfree(adapter->rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
err_dma:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
err_sw_init:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
err_mdio_ioremap:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	iounmap(hw->ce4100_gbe_mdio_base_virt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	iounmap(hw->hw_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
err_ioremap:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	free_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
err_alloc_etherdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
	pci_release_selected_regions(pdev, bars);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
err_pci_reg:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
 * e1000_remove - Device Removal Routine
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 * @pdev: PCI device information struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 * e1000_remove is called by the PCI subsystem to alert the driver
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 * that it should release a PCI device.  The could be caused by a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 * Hot-Plug event, or because the driver is going to be removed from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 * memory.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
static void e1000_remove(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	e1000_down_and_stop(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		ecdev_close(adapter->ecdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		ecdev_withdraw(adapter->ecdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		unregister_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	e1000_phy_hw_reset(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	kfree(adapter->rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	if (hw->mac_type == e1000_ce4100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		iounmap(hw->ce4100_gbe_mdio_base_virt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
	iounmap(hw->hw_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
	if (hw->flash_address)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		iounmap(hw->flash_address);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
	pci_release_selected_regions(pdev, adapter->bars);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	free_netdev(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
 * @adapter: board private structure to initialize
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
 * e1000_sw_init initializes the Adapter private data structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
 * e1000_init_hw_struct MUST be called before this function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
static int e1000_sw_init(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	adapter->num_tx_queues = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	adapter->num_rx_queues = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	if (e1000_alloc_queues(adapter)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		e_err(probe, "Unable to allocate memory for queues\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	/* Explicitly disable IRQ since the NIC can be in any state. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	spin_lock_init(&adapter->stats_lock);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	mutex_init(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	set_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
 * e1000_alloc_queues - Allocate memory for all rings
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
 * @adapter: board private structure to initialize
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
 * We allocate one ring per queue at run-time since we don't know the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
 * number of queues at compile-time.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
static int e1000_alloc_queues(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	if (!adapter->tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	if (!adapter->rx_ring) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		kfree(adapter->tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
 * e1000_open - Called when a network interface is made active
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 * Returns 0 on success, negative value on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
 * The open entry point is called when a network interface is made
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
 * active by the system (IFF_UP).  At this point all resources needed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
 * for transmit and receive operations are allocated, the interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
 * handler is registered with the OS, the watchdog task is started,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
 * and the stack is notified that the interface is ready.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
static int e1000_open(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	/* disallow open during test */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	if (test_bit(__E1000_TESTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	/* allocate transmit descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	err = e1000_setup_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		goto err_setup_tx;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	/* allocate receive descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	err = e1000_setup_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
		goto err_setup_rx;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	e1000_power_up_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
		e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	/* before we allocate an interrupt, we must be ready to handle it.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
	 * as soon as we call pci_request_irq, so we have to setup our
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	 * clean_rx handler before we do so.  */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	e1000_configure(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	err = e1000_request_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
		goto err_req_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	/* From here on the code is the same as e1000_up() */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	clear_bit(__E1000_DOWN, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		napi_enable(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		netif_start_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	/* fire a link status change interrupt to start the watchdog */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	ew32(ICS, E1000_ICS_LSC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
err_req_irq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	e1000_power_down_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	e1000_free_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
err_setup_rx:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	e1000_free_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
err_setup_tx:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
 * e1000_close - Disables a network interface
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
 * Returns 0, this is not allowed to fail
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
 * The close entry point is called when an interface is de-activated
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
 * by the OS.  The hardware is still under the drivers control, but
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
 * needs to be disabled.  A global MAC reset is issued to stop the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
 * hardware, and all transmit and receive resources are freed.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
static int e1000_close(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	e1000_power_down_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	e1000_free_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	e1000_free_all_tx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	e1000_free_all_rx_resources(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	/* kill manageability vlan ID if supported, but not if a vlan with
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	 * the same ID is registered on the host OS (let 8021q kill it) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	     !test_bit(adapter->mng_vlan_id, adapter->active_vlans)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
 * @start: address of beginning of memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
 * @len: length of memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
				  unsigned long len)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	unsigned long begin = (unsigned long)start;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	unsigned long end = begin + len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	/* First rev 82545 and 82546 need to not allow any memory
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	 * write location to cross 64k boundary due to errata 23 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	if (hw->mac_type == e1000_82545 ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	    hw->mac_type == e1000_ce4100 ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
	    hw->mac_type == e1000_82546) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
 * @txdr:    tx descriptor ring (for a specific queue) to setup
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
				    struct e1000_tx_ring *txdr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	int size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	size = sizeof(struct e1000_buffer) * txdr->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	txdr->buffer_info = vzalloc(size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	if (!txdr->buffer_info) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	/* round up to nearest 4K */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	txdr->size = ALIGN(txdr->size, 4096);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size, &txdr->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
					GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	if (!txdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
setup_tx_desc_die:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
		vfree(txdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		e_err(probe, "Unable to allocate memory for the Tx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		void *olddesc = txdr->desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		dma_addr_t olddma = txdr->dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		e_err(tx_err, "txdr align check failed: %u bytes at %p\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
		      txdr->size, txdr->desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		txdr->desc = dma_alloc_coherent(&pdev->dev, txdr->size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
						&txdr->dma, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		if (!txdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
			goto setup_tx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
			/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
			dma_free_coherent(&pdev->dev, txdr->size, txdr->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
					  txdr->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
			e_err(probe, "Unable to allocate aligned memory "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			      "for the transmit descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
			vfree(txdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
			/* Free old allocation, new allocation was successful */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			dma_free_coherent(&pdev->dev, txdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	memset(txdr->desc, 0, txdr->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	txdr->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	txdr->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
 * 				  (Descriptors) for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	int i, err = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	for (i = 0; i < adapter->num_tx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
			e_err(probe, "Allocation for Tx Queue %u failed\n", i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
			for (i-- ; i >= 0; i--)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
				e1000_free_tx_resources(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
							&adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
 * Configure the Tx unit of the MAC after a reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
static void e1000_configure_tx(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
	u64 tdba;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	u32 tdlen, tctl, tipg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	u32 ipgr1, ipgr2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	/* Setup the HW Tx Head and Tail descriptor pointers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	switch (adapter->num_tx_queues) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	case 1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		tdba = adapter->tx_ring[0].dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		tdlen = adapter->tx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
			sizeof(struct e1000_tx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		ew32(TDLEN, tdlen);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		ew32(TDBAH, (tdba >> 32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
		ew32(TDT, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
		ew32(TDH, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	/* Set the default values for the Tx Inter Packet Gap timer */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	if ((hw->media_type == e1000_media_type_fiber ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	     hw->media_type == e1000_media_type_internal_serdes))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	case e1000_82542_rev2_0:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	case e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		tipg = DEFAULT_82542_TIPG_IPGT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	ew32(TIPG, tipg);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	/* Set the Tx Interrupt Delay register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	ew32(TIDV, adapter->tx_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	if (hw->mac_type >= e1000_82540)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		ew32(TADV, adapter->tx_abs_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	/* Program the Transmit Control Register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	tctl &= ~E1000_TCTL_CT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	e1000_config_collision_dist(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	/* Setup Transmit Descriptor Settings for eop descriptor */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	/* only set IDE if we are delaying interrupts using the timers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	if (adapter->tx_int_delay)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	if (hw->mac_type < e1000_82543)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	/* Cache if we're 82544 running in PCI-X because we'll
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	 * need this to apply a workaround later in the send path. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	if (hw->mac_type == e1000_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	    hw->bus_type == e1000_bus_type_pcix)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		adapter->pcix_82544 = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
				    struct e1000_rx_ring *rxdr)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	int size, desc_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	size = sizeof(struct e1000_buffer) * rxdr->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	rxdr->buffer_info = vzalloc(size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	if (!rxdr->buffer_info) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	desc_len = sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	/* Round up to nearest 4K */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	rxdr->size = rxdr->count * desc_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	rxdr->size = ALIGN(rxdr->size, 4096);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
					GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	if (!rxdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		e_err(probe, "Unable to allocate memory for the Rx descriptor "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		      "ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
setup_rx_desc_die:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		vfree(rxdr->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		return -ENOMEM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		void *olddesc = rxdr->desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		dma_addr_t olddma = rxdr->dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		e_err(rx_err, "rxdr align check failed: %u bytes at %p\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		      rxdr->size, rxdr->desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
						&rxdr->dma, GFP_KERNEL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
		/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
		if (!rxdr->desc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
			e_err(probe, "Unable to allocate memory for the Rx "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
			      "descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
			goto setup_rx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
			/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			dma_free_coherent(&pdev->dev, rxdr->size, rxdr->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
					  rxdr->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
			e_err(probe, "Unable to allocate aligned memory for "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
			      "the Rx descriptor ring\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
			goto setup_rx_desc_die;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
			/* Free old allocation, new allocation was successful */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
			dma_free_coherent(&pdev->dev, rxdr->size, olddesc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
					  olddma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	memset(rxdr->desc, 0, rxdr->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	rxdr->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
	rxdr->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	rxdr->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
 * 				  (Descriptors) for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
 * Return 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	int i, err = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	for (i = 0; i < adapter->num_rx_queues; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
			e_err(probe, "Allocation for Rx Queue %u failed\n", i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
			for (i-- ; i >= 0; i--)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
				e1000_free_rx_resources(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
							&adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
 * e1000_setup_rctl - configure the receive control registers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
 * @adapter: Board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
static void e1000_setup_rctl(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		E1000_RCTL_RDMTS_HALF |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	if (hw->tbi_compatibility_on == 1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		rctl |= E1000_RCTL_SBP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
		rctl &= ~E1000_RCTL_SBP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		rctl &= ~E1000_RCTL_LPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		rctl |= E1000_RCTL_LPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	/* Setup buffer sizes */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	rctl &= ~E1000_RCTL_SZ_4096;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	rctl |= E1000_RCTL_BSEX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	switch (adapter->rx_buffer_len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		case E1000_RXBUFFER_2048:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
			rctl |= E1000_RCTL_SZ_2048;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
			rctl &= ~E1000_RCTL_BSEX;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		case E1000_RXBUFFER_4096:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
			rctl |= E1000_RCTL_SZ_4096;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		case E1000_RXBUFFER_8192:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
			rctl |= E1000_RCTL_SZ_8192;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		case E1000_RXBUFFER_16384:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
			rctl |= E1000_RCTL_SZ_16384;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	/* This is useful for sniffing bad packets. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	if (adapter->netdev->features & NETIF_F_RXALL) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
		/* UPE and MPE will be handled by normal PROMISC logic
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
		 * in e1000e_set_rx_mode */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
			  E1000_RCTL_DPF | /* Allow filtered pause */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		 * and that breaks VLANs.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 * Configure the Rx unit of the MAC after a reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
static void e1000_configure_rx(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	u64 rdba;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	u32 rdlen, rctl, rxcsum;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		rdlen = adapter->rx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		        sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		rdlen = adapter->rx_ring[0].count *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		        sizeof(struct e1000_rx_desc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
		adapter->clean_rx = e1000_clean_rx_irq;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
	/* disable receives while setting up the descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	/* set the Receive Delay Timer Register */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	ew32(RDTR, adapter->rx_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	if (hw->mac_type >= e1000_82540) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		ew32(RADV, adapter->rx_abs_int_delay);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		if (adapter->itr_setting != 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
			ew32(ITR, 1000000000 / (adapter->itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	 * the Base and Length of the Rx Descriptor Ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	switch (adapter->num_rx_queues) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	case 1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		rdba = adapter->rx_ring[0].dma;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		ew32(RDLEN, rdlen);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		ew32(RDBAH, (rdba >> 32));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		ew32(RDT, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		ew32(RDH, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		rxcsum = er32(RXCSUM);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		if (adapter->rx_csum)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
			rxcsum |= E1000_RXCSUM_TUOFL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
			/* don't need to clear IPPCSE as it defaults to 0 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
			rxcsum &= ~E1000_RXCSUM_TUOFL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
		ew32(RXCSUM, rxcsum);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	/* Enable Receives */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	ew32(RCTL, rctl | E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
 * e1000_free_tx_resources - Free Tx Resources per Queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
 * @tx_ring: Tx descriptor ring for a specific queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
 * Free all transmit software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
				    struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	e1000_clean_tx_ring(adapter, tx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	vfree(tx_ring->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	tx_ring->buffer_info = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
			  tx_ring->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	tx_ring->desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
 * Free all transmit software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	for (i = 0; i < adapter->num_tx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
					     struct e1000_buffer *buffer_info)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	if (buffer_info->dma) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		if (buffer_info->mapped_as_page)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
				       buffer_info->length, DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
					 buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
					 DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
	if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
		dev_kfree_skb_any(buffer_info->skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
		buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	buffer_info->time_stamp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	/* buffer_info must be completely set up in the transmit path */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
 * e1000_clean_tx_ring - Free Tx Buffers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
 * @tx_ring: ring to be cleaned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
				struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	unsigned long size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	/* Free all the Tx ring sk_buffs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	for (i = 0; i < tx_ring->count; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	netdev_reset_queue(adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	size = sizeof(struct e1000_buffer) * tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	memset(tx_ring->buffer_info, 0, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	/* Zero out the descriptor ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	memset(tx_ring->desc, 0, tx_ring->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	tx_ring->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	tx_ring->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	tx_ring->last_tx_tso = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	writel(0, hw->hw_addr + tx_ring->tdh);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	writel(0, hw->hw_addr + tx_ring->tdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	for (i = 0; i < adapter->num_tx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
 * e1000_free_rx_resources - Free Rx Resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
 * @rx_ring: ring to clean the resources from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
 * Free all receive software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
				    struct e1000_rx_ring *rx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	e1000_clean_rx_ring(adapter, rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	vfree(rx_ring->buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	rx_ring->buffer_info = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
			  rx_ring->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	rx_ring->desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
 * Free all receive software resources
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	for (i = 0; i < adapter->num_rx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
 * @rx_ring: ring to free buffers from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
				struct e1000_rx_ring *rx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	unsigned long size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	/* Free all the Rx ring sk_buffs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	for (i = 0; i < rx_ring->count; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		if (buffer_info->dma &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
		    adapter->clean_rx == e1000_clean_rx_irq) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
			dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
			                 buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
					 DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
		} else if (buffer_info->dma &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
			dma_unmap_page(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
				       buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
				       DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		if (buffer_info->page) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
			put_page(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
			buffer_info->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
			dev_kfree_skb(buffer_info->skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	/* there also may be some cached data from a chained receive */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	if (rx_ring->rx_skb_top) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
		dev_kfree_skb(rx_ring->rx_skb_top);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		rx_ring->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	size = sizeof(struct e1000_buffer) * rx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	memset(rx_ring->buffer_info, 0, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	/* Zero out the descriptor ring */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	memset(rx_ring->desc, 0, rx_ring->size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	rx_ring->next_to_clean = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	rx_ring->next_to_use = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	writel(0, hw->hw_addr + rx_ring->rdh);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	writel(0, hw->hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	for (i = 0; i < adapter->num_rx_queues; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
 * and memory write and invalidate disabled for certain operations
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	e1000_pci_clear_mwi(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
	rctl |= E1000_RCTL_RST;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	mdelay(5);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	if (!adapter->ecdev && netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
		e1000_clean_all_rx_rings(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	rctl &= ~E1000_RCTL_RST;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	mdelay(5);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
		e1000_pci_set_mwi(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	if (!adapter->netdev && netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
		/* No need to loop, because 82542 supports only 1 queue */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
		e1000_configure_rx(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
			/* fill rx ring completely! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
			adapter->alloc_rx_buf(adapter, ring, ring->count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
			/* this one leaves the last ring element unallocated! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
 * e1000_set_mac - Change the Ethernet Address of the NIC
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
 * @p: pointer to an address structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
static int e1000_set_mac(struct net_device *netdev, void *p)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	struct sockaddr *addr = p;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	if (!is_valid_ether_addr(addr->sa_data))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
		return -EADDRNOTAVAIL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	/* 82542 2.0 needs to be in reset to write receive address registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
		e1000_enter_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	e1000_rar_set(hw, hw->mac_addr, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
		e1000_leave_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
 * The set_rx_mode entry point is called whenever the unicast or multicast
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
 * address lists or the network interface flags are updated. This routine is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
 * responsible for configuring the hardware for proper unicast, multicast,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
 * promiscuous mode, and all-multi behavior.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
static void e1000_set_rx_mode(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	struct netdev_hw_addr *ha;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	bool use_uc = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	u32 hash_value;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	int i, rar_entries = E1000_RAR_ENTRIES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	int mta_reg_count = E1000_NUM_MTA_REGISTERS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	if (!mcarray) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		e_err(probe, "memory allocation failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	/* Check for Promiscuous and All Multicast modes */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	if (netdev->flags & IFF_PROMISC) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		rctl &= ~E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		if (netdev->flags & IFF_ALLMULTI)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
			rctl |= E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
			rctl &= ~E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		/* Enable VLAN filter if there is a VLAN */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		if (e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
			rctl |= E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	if (netdev_uc_count(netdev) > rar_entries - 1) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		rctl |= E1000_RCTL_UPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	} else if (!(netdev->flags & IFF_PROMISC)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		rctl &= ~E1000_RCTL_UPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		use_uc = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	/* 82542 2.0 needs to be in reset to write receive address registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		e1000_enter_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	/* load the first 14 addresses into the exact filters 1-14. Unicast
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	 * addresses take precedence to avoid disabling unicast filtering
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	 * when possible.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	 * RAR 0 is used for the station MAC address
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	 * if there are not 14 addresses, go ahead and clear the filters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	i = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	if (use_uc)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
		netdev_for_each_uc_addr(ha, netdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
			if (i == rar_entries)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
			e1000_rar_set(hw, ha->addr, i++);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	netdev_for_each_mc_addr(ha, netdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
		if (i == rar_entries) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
			/* load any remaining addresses into the hash table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			u32 hash_reg, hash_bit, mta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
			hash_value = e1000_hash_mc_addr(hw, ha->addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			hash_reg = (hash_value >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
			hash_bit = hash_value & 0x1F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
			mta = (1 << hash_bit);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
			mcarray[hash_reg] |= mta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			e1000_rar_set(hw, ha->addr, i++);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	for (; i < rar_entries; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
		E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	/* write the hash table completely, write from bottom to avoid
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	 * both stupid write combining chipsets, and flushing each write */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	for (i = mta_reg_count - 1; i >= 0 ; i--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		 * If we are on an 82544 has an errata where writing odd
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		 * offsets overwrites the previous even offset, but writing
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		 * backwards over the range solves the issue by always
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		 * writing the odd offset first
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	if (hw->mac_type == e1000_82542_rev2_0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
		e1000_leave_82542_rst(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	kfree(mcarray);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
 * e1000_update_phy_info_task - get phy info
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
 * Need to wait a few seconds after link up to get diagnostic information from
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
 * the phy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
static void e1000_update_phy_info_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
						     phy_info_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
 * e1000_82547_tx_fifo_stall_task - task to complete work
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
static void e1000_82547_tx_fifo_stall_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
						     fifo_stall_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	u32 tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	if (atomic_read(&adapter->tx_fifo_stall)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		if ((er32(TDT) == er32(TDH)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
		   (er32(TDFT) == er32(TDFH)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
		   (er32(TDFTS) == er32(TDFHS))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
			ew32(TDFT, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
			ew32(TDFH, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
			ew32(TDFTS, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
			ew32(TDFHS, adapter->tx_head_addr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
			ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
			E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
			adapter->tx_fifo_head = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
			atomic_set(&adapter->tx_fifo_stall, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
			netif_wake_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		} else if (!test_bit(__E1000_DOWN, &adapter->flags)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
			schedule_delayed_work(&adapter->fifo_stall_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
bool e1000_has_link(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	bool link_active = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	/* get_link_status is set on LSC (link status) interrupt or rx
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	 * sequence error interrupt (except on intel ce4100).
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	 * get_link_status will stay false until the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	 * e1000_check_for_link establishes link for copper adapters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	 * ONLY
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	switch (hw->media_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	case e1000_media_type_copper:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		if (hw->mac_type == e1000_ce4100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			hw->get_link_status = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		if (hw->get_link_status) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
			e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
			link_active = !hw->get_link_status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
			link_active = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	case e1000_media_type_fiber:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
		e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	case e1000_media_type_internal_serdes:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		e1000_check_for_link(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
		link_active = hw->serdes_has_link;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	return link_active;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
 * e1000_watchdog - work function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
 * @work: work struct contained inside adapter struct
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
static void e1000_watchdog(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	struct e1000_adapter *adapter = container_of(work,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
						     struct e1000_adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
						     watchdog_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	struct e1000_tx_ring *txdr = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	u32 link, tctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	mutex_lock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
	link = e1000_has_link(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	if (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		goto link_up;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	if (link) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			u32 ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
			bool txb2b __attribute__ ((unused)) = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			/* update snapshot of PHY registers on LSC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
			e1000_get_speed_and_duplex(hw,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			                           &adapter->link_speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
			                           &adapter->link_duplex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
			ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
			pr_info("%s NIC Link is Up %d Mbps %s, "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
				"Flow Control: %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
				netdev->name,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
				adapter->link_speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
				adapter->link_duplex == FULL_DUPLEX ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
				"Full Duplex" : "Half Duplex",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
				((ctrl & E1000_CTRL_TFCE) && (ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
				E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
				E1000_CTRL_RFCE) ? "RX" : ((ctrl &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
				E1000_CTRL_TFCE) ? "TX" : "None")));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
			/* adjust timeout factor according to speed/duplex */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
			adapter->tx_timeout_factor = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
			switch (adapter->link_speed) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
			case SPEED_10:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
				txb2b = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				adapter->tx_timeout_factor = 16;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
			case SPEED_100:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
				txb2b = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
				/* maybe add some timeout factor ? */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
			/* enable transmits in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
			tctl = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
			tctl |= E1000_TCTL_EN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
			ew32(TCTL, tctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
			if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
				ecdev_set_link(adapter->ecdev, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
			else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
				netif_carrier_on(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
				if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
					schedule_delayed_work(&adapter->phy_info_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
							2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
			adapter->smartspeed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			adapter->link_speed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			adapter->link_duplex = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			pr_info("%s NIC Link is Down\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
				netdev->name);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
			if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
				ecdev_set_link(adapter->ecdev, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
				netif_carrier_off(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
				if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
					schedule_delayed_work(&adapter->phy_info_task,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
							2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		e1000_smartspeed(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
link_up:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	e1000_update_stats(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	adapter->tpt_old = adapter->stats.tpt;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
	adapter->colc_old = adapter->stats.colc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	adapter->gorcl_old = adapter->stats.gorcl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	adapter->gotcl_old = adapter->stats.gotcl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	e1000_update_adaptive(hw);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
			/* We've lost link, so the controller stops DMA,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
			 * but we've got queued Tx work that's never going
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
			 * to get done, so reset controller to flush Tx.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
			 * (Do the reset outside of interrupt context). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
			adapter->tx_timeout_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
			schedule_work(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
			/* exit immediately since reset is imminent */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			goto unlock;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	/* Simple mode for Interrupt Throttle Rate (ITR) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
	if (hw->mac_type >= e1000_82540 && adapter->itr_setting == 4) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
		 * Total asymmetrical Tx or Rx gets ITR=8000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
		 * everyone else is between 2000-8000.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		u32 goc = (adapter->gotcl + adapter->gorcl) / 10000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		u32 dif = (adapter->gotcl > adapter->gorcl ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			    adapter->gotcl - adapter->gorcl :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			    adapter->gorcl - adapter->gotcl) / 10000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		ew32(ITR, 1000000000 / (itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	/* Cause software interrupt to ensure rx ring is cleaned */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	ew32(ICS, E1000_ICS_RXDMT0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
	/* Force detection of hung controller every watchdog period */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	adapter->detect_tx_hung = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	/* Reschedule the task */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
		schedule_delayed_work(&adapter->watchdog_task, 2 * HZ);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
unlock:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	mutex_unlock(&adapter->mutex);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
enum latency_range {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	lowest_latency = 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	low_latency = 1,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	bulk_latency = 2,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	latency_invalid = 255
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
 * e1000_update_itr - update the dynamic ITR value based on statistics
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
 * @adapter: pointer to adapter
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
 * @itr_setting: current adapter->itr
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
 * @packets: the number of packets during this measurement interval
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
 * @bytes: the number of bytes during this measurement interval
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
 *      Stores a new ITR value based on packets and byte
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
 *      counts during the last interrupt.  The advantage of per interrupt
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
 *      computation is faster updates and more accurate ITR for the current
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
 *      traffic pattern.  Constants in this function were computed
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
 *      based on theoretical maximum wire speed and thresholds were set based
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
 *      on testing data as well as attempting to minimize response time
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
 *      while increasing bulk throughput.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
 *      this functionality is controlled by the InterruptThrottleRate module
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
 *      parameter (see e1000_param.c)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
				     u16 itr_setting, int packets, int bytes)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	unsigned int retval = itr_setting;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	if (unlikely(hw->mac_type < e1000_82540))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		goto update_itr_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
	if (packets == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		goto update_itr_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	switch (itr_setting) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	case lowest_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		/* jumbo frames get bulk treatment*/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		if (bytes/packets > 8000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
			retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		else if ((packets < 5) && (bytes > 512))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
			retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	case low_latency:  /* 50 usec aka 20000 ints/s */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
		if (bytes > 10000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
			/* jumbo frames need bulk latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
			if (bytes/packets > 8000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
				retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
			else if ((packets < 10) || ((bytes/packets) > 1200))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
				retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
			else if ((packets > 35))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
				retval = lowest_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		} else if (bytes/packets > 2000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
			retval = bulk_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		else if (packets <= 2 && bytes < 512)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
			retval = lowest_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	case bulk_latency: /* 250 usec aka 4000 ints/s */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		if (bytes > 25000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
			if (packets > 35)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
				retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
		} else if (bytes < 6000) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
			retval = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
update_itr_done:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
static void e1000_set_itr(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	u16 current_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	u32 new_itr = adapter->itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	if (unlikely(hw->mac_type < e1000_82540))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	if (unlikely(adapter->link_speed != SPEED_1000)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		current_itr = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
		new_itr = 4000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		goto set_itr_now;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	adapter->tx_itr = e1000_update_itr(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	                            adapter->tx_itr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
	                            adapter->total_tx_packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	                            adapter->total_tx_bytes);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
		adapter->tx_itr = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	adapter->rx_itr = e1000_update_itr(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	                            adapter->rx_itr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	                            adapter->total_rx_packets,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	                            adapter->total_rx_bytes);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		adapter->rx_itr = low_latency;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	switch (current_itr) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	/* counts and packets in update_itr are dependent on these numbers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	case lowest_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		new_itr = 70000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
	case low_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		new_itr = 20000; /* aka hwitr = ~200 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
	case bulk_latency:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		new_itr = 4000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
set_itr_now:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	if (new_itr != adapter->itr) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		/* this attempts to bias the interrupt rate towards Bulk
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		 * by adding intermediate steps when interrupt rate is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		 * increasing */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		new_itr = new_itr > adapter->itr ?
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		             min(adapter->itr + (new_itr >> 2), new_itr) :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		             new_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
		adapter->itr = new_itr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		ew32(ITR, 1000000000 / (new_itr * 256));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
#define E1000_TX_FLAGS_CSUM		0x00000001
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
#define E1000_TX_FLAGS_VLAN		0x00000002
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
#define E1000_TX_FLAGS_TSO		0x00000004
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
#define E1000_TX_FLAGS_IPV4		0x00000008
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
#define E1000_TX_FLAGS_NO_FCS		0x00000010
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
#define E1000_TX_FLAGS_VLAN_SHIFT	16
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
static int e1000_tso(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	struct e1000_context_desc *context_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	u32 cmd_length = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	u16 ipcse = 0, tucse, mss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	if (skb_is_gso(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		if (skb_header_cloned(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
			if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
				return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		mss = skb_shinfo(skb)->gso_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
		if (skb->protocol == htons(ETH_P_IP)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
			struct iphdr *iph = ip_hdr(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
			iph->tot_len = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
			iph->check = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
								 iph->daddr, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
								 IPPROTO_TCP,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
								 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
			cmd_length = E1000_TXD_CMD_IP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
			ipcse = skb_transport_offset(skb) - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			ipv6_hdr(skb)->payload_len = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
			tcp_hdr(skb)->check =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
						 &ipv6_hdr(skb)->daddr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
						 0, IPPROTO_TCP, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
			ipcse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		ipcss = skb_network_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		tucss = skb_transport_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
		tucse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
		i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
		context_desc->upper_setup.tcp_fields.tucss = tucss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		context_desc->upper_setup.tcp_fields.tucso = tucso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
		buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		if (++i == tx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
static bool e1000_tx_csum(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	struct e1000_context_desc *context_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	u8 css;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	u32 cmd_len = E1000_TXD_CMD_DEXT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	if (skb->ip_summed != CHECKSUM_PARTIAL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	switch (skb->protocol) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	case cpu_to_be16(ETH_P_IP):
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
			cmd_len |= E1000_TXD_CMD_TCP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
	case cpu_to_be16(ETH_P_IPV6):
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		/* XXX not handling all IPV6 headers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			cmd_len |= E1000_TXD_CMD_TCP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
		if (unlikely(net_ratelimit()))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
			e_warn(drv, "checksum_partial proto=%x!\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
			       skb->protocol);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	css = skb_checksum_start_offset(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	context_desc->lower_setup.ip_config = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	context_desc->upper_setup.tcp_fields.tucss = css;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	context_desc->upper_setup.tcp_fields.tucso =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		css + skb->csum_offset;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	context_desc->upper_setup.tcp_fields.tucse = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	context_desc->tcp_seg_setup.data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
#define E1000_MAX_TXD_PWR	12
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
static int e1000_tx_map(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
			struct e1000_tx_ring *tx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
			struct sk_buff *skb, unsigned int first,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
			unsigned int max_per_txd, unsigned int nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
			unsigned int mss)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	unsigned int len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	unsigned int offset = 0, size, count = 0, i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	unsigned int f, bytecount, segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	while (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		size = min(len, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		/* Workaround for Controller erratum --
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		 * descriptor for non-tso packet in a linear SKB that follows a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		 * tso gets written back prematurely before the data is fully
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		 * DMA'd to the controller */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		if (!skb->data_len && tx_ring->last_tx_tso &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
		    !skb_is_gso(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
			tx_ring->last_tx_tso = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		/* Workaround for premature desc write-backs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
		 * in TSO mode.  Append 4-byte sentinel desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		if (unlikely(mss && !nr_frags && size == len && size > 8))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		/* work-around for errata 10 and it applies
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		 * to all controllers in PCI-X mode
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		 * The fix is to make sure that the first descriptor of a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		                (size > 2015) && count == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		        size = 2015;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		 * terminating buffers within evenly-aligned dwords. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
		if (unlikely(adapter->pcix_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		   size > 4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
			size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		buffer_info->length = size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
		/* set time_stamp *before* dma to help avoid a possible race */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		buffer_info->mapped_as_page = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		buffer_info->dma = dma_map_single(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
						  skb->data + offset,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
						  size,	DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
			goto dma_error;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		len -= size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		offset += size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
		if (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
			i++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
			if (unlikely(i == tx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
				i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	for (f = 0; f < nr_frags; f++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		const struct skb_frag_struct *frag;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		frag = &skb_shinfo(skb)->frags[f];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
		len = skb_frag_size(frag);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		offset = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		while (len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
			unsigned long bufend;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
			i++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
			if (unlikely(i == tx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
				i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
			buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
			size = min(len, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
			/* Workaround for premature desc write-backs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
			 * in TSO mode.  Append 4-byte sentinel desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
				size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
			/* Workaround for potential 82544 hang in PCI-X.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
			 * Avoid terminating buffers within evenly-aligned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
			 * dwords. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
			bufend = (unsigned long)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
				page_to_phys(skb_frag_page(frag));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
			bufend += offset + size - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
			if (unlikely(adapter->pcix_82544 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
				     !(bufend & 4) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
				     size > 4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
				size -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
			buffer_info->length = size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
			buffer_info->time_stamp = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
			buffer_info->mapped_as_page = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
						offset, size, DMA_TO_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
				goto dma_error;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			buffer_info->next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
			len -= size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
			offset += size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
			count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	segs = skb_shinfo(skb)->gso_segs ?: 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	/* multiply data chunks by size of headers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	tx_ring->buffer_info[i].skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	tx_ring->buffer_info[i].segs = segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	tx_ring->buffer_info[i].bytecount = bytecount;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	tx_ring->buffer_info[first].next_to_watch = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	return count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
dma_error:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	dev_err(&pdev->dev, "TX DMA map failed\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	if (count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		count--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	while (count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
		if (i==0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
			i += tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		i--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
static void e1000_tx_queue(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
			   struct e1000_tx_ring *tx_ring, int tx_flags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
			   int count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	struct e1000_tx_desc *tx_desc = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		             E1000_TXD_CMD_TSE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		txd_lower |= E1000_TXD_CMD_VLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	i = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	while (count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		tx_desc->lower.data =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
			cpu_to_le32(txd_lower | buffer_info->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
		tx_desc->upper.data = cpu_to_le32(txd_upper);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	tx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	writel(i, hw->hw_addr + tx_ring->tdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
	/* we need this if more than one processor can write to our tail
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	 * at a time, it syncronizes IO on IA64/Altix systems */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	mmiowb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
/* 82547 workaround to avoid controller hang in half-duplex environment.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
 * The workaround is to avoid queuing a large packet that would span
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
 * the internal Tx FIFO ring boundary by notifying the stack to resend
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
 * to the beginning of the Tx FIFO.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
#define E1000_FIFO_HDR			0x10
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
#define E1000_82547_PAD_LEN		0x3E0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
				       struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	if (adapter->link_duplex != HALF_DUPLEX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		goto no_fifo_stall_required;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	if (atomic_read(&adapter->tx_fifo_stall))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		return 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		atomic_set(&adapter->tx_fifo_stall, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		return 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
no_fifo_stall_required:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	adapter->tx_fifo_head += skb_fifo_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	/* Herbert's original patch had:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	 *  smp_mb__after_netif_stop_queue();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	 * but since that doesn't exist yet, just open code it. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	smp_mb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	/* We need to check again in a case another CPU has just
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	 * made room available. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	/* A reprieve! */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	netif_start_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	++adapter->restart_queue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
static int e1000_maybe_stop_tx(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
                               struct e1000_tx_ring *tx_ring, int size)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	return __e1000_maybe_stop_tx(netdev, size);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
				    struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	struct e1000_tx_ring *tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	unsigned int tx_flags = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	unsigned int len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	unsigned int nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	unsigned int mss;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	int count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	int tso;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	unsigned int f;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	/* This goes back to the question of how to logically map a tx queue
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	 * to a flow.  Right now, performance is impacted slightly negatively
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	 * if using multiple tx queues.  If the stack breaks away from a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	 * single qdisc implementation, we can look at this again. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	if (unlikely(skb->len <= 0)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
			dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	/* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	 * packets may get corrupted during padding by HW.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	 * To WA this issue, pad all small packets manually.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	if (skb->len < ETH_ZLEN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		if (skb_pad(skb, ETH_ZLEN - skb->len))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
			return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		skb->len = ETH_ZLEN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		skb_set_tail_pointer(skb, ETH_ZLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	mss = skb_shinfo(skb)->gso_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	/* The controller does a simple calculation to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	 * make sure there is enough room in the FIFO before
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	 * initiating the DMA for each buffer.  The calc is:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	 * 4 = ceil(buffer len/mss).  To make sure we don't
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	 * overrun the FIFO, adjust the max buffer len if mss
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	 * drops. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	if (mss) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
		u8 hdr_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
		max_per_txd = min(mss << 2, max_per_txd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		max_txd_pwr = fls(max_per_txd) - 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
		if (skb->data_len && hdr_len == len) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
			switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
				unsigned int pull_size;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
			case e1000_82544:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
				/* Make sure we have room to chop off 4 bytes,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
				 * and that the end alignment will work out to
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
				 * this hardware's requirements
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
				 * NOTE: this is a TSO only workaround
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
				 * if end byte alignment not correct move us
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
				 * into the next dword */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
				/* fall through */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
				pull_size = min((unsigned int)4, skb->data_len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
				if (!__pskb_pull_tail(skb, pull_size)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
					e_err(drv, "__pskb_pull_tail "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
					      "failed.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
					if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
						dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
					}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
					return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
				len = skb_headlen(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
			default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
				/* do nothing */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	/* reserve a descriptor for the offload context */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	/* Controller Erratum workaround */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	count += TXD_USE_COUNT(len, max_txd_pwr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	if (adapter->pcix_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	/* work-around for errata 10 and it applies to all controllers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	 * in PCI-X mode, so add one more descriptor to the count
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
			(len > 2015)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	nr_frags = skb_shinfo(skb)->nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	for (f = 0; f < nr_frags; f++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
				       max_txd_pwr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	if (adapter->pcix_82544)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
		count += nr_frags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	/* need: count + 2 desc gap to keep tail from touching
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	 * head, otherwise try next time */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		return NETDEV_TX_BUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	if (unlikely((hw->mac_type == e1000_82547) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
		     (e1000_82547_fifo_workaround(adapter, skb)))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
			netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
			if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
				schedule_delayed_work(&adapter->fifo_stall_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		return NETDEV_TX_BUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	if (vlan_tx_tag_present(skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		tx_flags |= E1000_TX_FLAGS_VLAN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	first = tx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	tso = e1000_tso(adapter, tx_ring, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	if (tso < 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
			dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
		return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	if (likely(tso)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		if (likely(hw->mac_type != e1000_82544))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
			tx_ring->last_tx_tso = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		tx_flags |= E1000_TX_FLAGS_TSO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
		tx_flags |= E1000_TX_FLAGS_CSUM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	if (likely(skb->protocol == htons(ETH_P_IP)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		tx_flags |= E1000_TX_FLAGS_IPV4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	if (unlikely(skb->no_fcs))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
	count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	                     nr_frags, mss);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	if (count) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
		netdev_sent_queue(netdev, skb->len);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		skb_tx_timestamp(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
		e1000_tx_queue(adapter, tx_ring, tx_flags, count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
			/* Make sure there is space in the ring for the next send. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
			e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
			dev_kfree_skb_any(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		tx_ring->buffer_info[first].time_stamp = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		tx_ring->next_to_use = first;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	return NETDEV_TX_OK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
#define NUM_REGS 38 /* 1 based count */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
static void e1000_regdump(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	u32 regs[NUM_REGS];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	u32 *regs_buff = regs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	int i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	static const char * const reg_name[] = {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		"CTRL",  "STATUS",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
		"RCTL", "RDLEN", "RDH", "RDT", "RDTR",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		"TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		"TIDV", "TXDCTL", "TADV", "TARC0",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
		"TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
		"TXDCTL1", "TARC1",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		"CTRL_EXT", "ERT", "RDBAL", "RDBAH",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
		"TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		"RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	};
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	regs_buff[0]  = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	regs_buff[1]  = er32(STATUS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	regs_buff[2]  = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	regs_buff[3]  = er32(RDLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	regs_buff[4]  = er32(RDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	regs_buff[5]  = er32(RDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	regs_buff[6]  = er32(RDTR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	regs_buff[7]  = er32(TCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	regs_buff[8]  = er32(TDBAL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	regs_buff[9]  = er32(TDBAH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
	regs_buff[10] = er32(TDLEN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	regs_buff[11] = er32(TDH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	regs_buff[12] = er32(TDT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	regs_buff[13] = er32(TIDV);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	regs_buff[14] = er32(TXDCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	regs_buff[15] = er32(TADV);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	regs_buff[16] = er32(TARC0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	regs_buff[17] = er32(TDBAL1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	regs_buff[18] = er32(TDBAH1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	regs_buff[19] = er32(TDLEN1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	regs_buff[20] = er32(TDH1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	regs_buff[21] = er32(TDT1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	regs_buff[22] = er32(TXDCTL1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	regs_buff[23] = er32(TARC1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	regs_buff[24] = er32(CTRL_EXT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	regs_buff[25] = er32(ERT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	regs_buff[26] = er32(RDBAL0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	regs_buff[27] = er32(RDBAH0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	regs_buff[28] = er32(TDFH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	regs_buff[29] = er32(TDFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	regs_buff[30] = er32(TDFHS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	regs_buff[31] = er32(TDFTS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	regs_buff[32] = er32(TDFPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	regs_buff[33] = er32(RDFH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	regs_buff[34] = er32(RDFT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	regs_buff[35] = er32(RDFHS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	regs_buff[36] = er32(RDFTS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	regs_buff[37] = er32(RDFPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	pr_info("Register dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	for (i = 0; i < NUM_REGS; i++)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		pr_info("%-15s  %08x\n", reg_name[i], regs_buff[i]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
 * e1000_dump: Print registers, tx ring and rx ring
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
static void e1000_dump(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	/* this code doesn't handle multiple rings */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	struct e1000_rx_ring *rx_ring = adapter->rx_ring;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
	if (!netif_msg_hw(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	/* Print Registers */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	e1000_regdump(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	 * transmit dump
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	pr_info("TX Desc ring0 dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	 * Legacy Transmit Descriptor
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	 *   +--------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	 *   63       48 47        36 35    32 31     24 23    16 15        0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	 *   63      48 47    40 39       32 31             16 15    8 7      0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	 * Extended Data Descriptor (DTYP=0x1)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	 * 0 |                     Buffer Address [63:0]                      |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	 *   +----------------------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestmp         bi->skb\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	if (!netif_msg_tx_done(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
		goto rx_ring_summary;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		struct my_u { __le64 a; __le64 b; };
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		struct my_u *u = (struct my_u *)tx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		const char *type;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
			type = "NTC/U";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		else if (i == tx_ring->next_to_use)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
			type = "NTU";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		else if (i == tx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
			type = "NTC";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
			type = "";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
			((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
			le64_to_cpu(u->a), le64_to_cpu(u->b),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
			(u64)buffer_info->dma, buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
			buffer_info->next_to_watch,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
			(u64)buffer_info->time_stamp, buffer_info->skb, type);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
rx_ring_summary:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	 * receive dump
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	pr_info("\nRX Desc ring dump\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	/* Legacy Receive Descriptor Format
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
	 * |                Buffer Address [63:0]                |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	 * +-----------------------------------------------------+
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	 * 63       48 47    40 39      32 31         16 15      0
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	pr_info("R[desc]      [address 63:0  ] [vl er S cks ln] [bi->dma       ] [bi->skb]\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	if (!netif_msg_rx_status(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		goto exit;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		struct my_u { __le64 a; __le64 b; };
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		struct my_u *u = (struct my_u *)rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		const char *type;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		if (i == rx_ring->next_to_use)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
			type = "NTU";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		else if (i == rx_ring->next_to_clean)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
			type = "NTC";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
			type = "";
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		pr_info("R[0x%03X]     %016llX %016llX %016llX %p %s\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
			i, le64_to_cpu(u->a), le64_to_cpu(u->b),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
			(u64)buffer_info->dma, buffer_info->skb, type);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	} /* for */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	/* dump the descriptor caches */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	/* rx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	pr_info("Rx descriptor cache in 64bit format\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	for (i = 0x6000; i <= 0x63FF ; i += 0x10) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		pr_info("R%04X: %08X|%08X %08X|%08X\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
			i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
			readl(adapter->hw.hw_addr + i+4),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
			readl(adapter->hw.hw_addr + i),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
			readl(adapter->hw.hw_addr + i+12),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
			readl(adapter->hw.hw_addr + i+8));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	/* tx */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	pr_info("Tx descriptor cache in 64bit format\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	for (i = 0x7000; i <= 0x73FF ; i += 0x10) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		pr_info("T%04X: %08X|%08X %08X|%08X\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
			i,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
			readl(adapter->hw.hw_addr + i+4),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
			readl(adapter->hw.hw_addr + i),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
			readl(adapter->hw.hw_addr + i+12),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
			readl(adapter->hw.hw_addr + i+8));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
exit:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
 * e1000_tx_timeout - Respond to a Tx Hang
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
static void e1000_tx_timeout(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	/* Do the reset outside of interrupt context */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	adapter->tx_timeout_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	schedule_work(&adapter->reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
static void e1000_reset_task(struct work_struct *work)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	struct e1000_adapter *adapter =
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
		container_of(work, struct e1000_adapter, reset_task);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
	if (test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	e_err(drv, "Reset adapter\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	e1000_reinit_safe(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 * e1000_get_stats - Get System Network Statistics
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
 * Returns the address of the device statistics structure.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
 * The statistics are actually updated from the watchdog.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	/* only return the current stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	return &netdev->stats;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
 * e1000_change_mtu - Change the Maximum Transfer Unit
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
 * @netdev: network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
 * @new_mtu: new value for maximum frame size
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
 * Returns 0 on success, negative on failure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		e_err(probe, "Invalid MTU setting\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	/* Adapter-specific max frame size limits. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	switch (hw->mac_type) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	case e1000_undefined ... e1000_82542_rev2_1:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
			e_err(probe, "Jumbo Frames not supported.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
			return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
		msleep(1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	/* e1000_down has a dependency on max_frame_size */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	hw->max_frame_size = max_frame;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	 * means we reserve 2 more, this pushes us to allocate from the next
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	 * larger slab size.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	 * i.e. RXBUFFER_2048 --> size-4096 slab
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	 *  fragmented skbs */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	if (max_frame <= E1000_RXBUFFER_2048)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
		adapter->rx_buffer_len = PAGE_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	/* adjust allocation if LPE protects us, and we aren't using SBP */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	if (!hw->tbi_compatibility_on &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	pr_info("%s changing MTU from %d to %d\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
		netdev->name, netdev->mtu, new_mtu);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	netdev->mtu = new_mtu;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
		e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
	clear_bit(__E1000_RESETTING, &adapter->flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 * e1000_update_stats - Update the board statistics counters
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
void e1000_update_stats(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	unsigned long flags = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	u16 phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	 * Prevent stats update while adapter is being reset, or if the pci
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
	 * connection is down.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	if (adapter->link_speed == 0)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
	if (pci_channel_offline(pdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
	/* these counters are modified from e1000_tbi_adjust_stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	 * called from the interrupt context, so they must only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	 * be written while holding adapter->stats_lock
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	adapter->stats.crcerrs += er32(CRCERRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	adapter->stats.gprc += er32(GPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	adapter->stats.gorcl += er32(GORCL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
	adapter->stats.gorch += er32(GORCH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	adapter->stats.bprc += er32(BPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	adapter->stats.mprc += er32(MPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	adapter->stats.roc += er32(ROC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	adapter->stats.prc64 += er32(PRC64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	adapter->stats.prc127 += er32(PRC127);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	adapter->stats.prc255 += er32(PRC255);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
	adapter->stats.prc511 += er32(PRC511);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	adapter->stats.prc1023 += er32(PRC1023);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	adapter->stats.prc1522 += er32(PRC1522);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	adapter->stats.symerrs += er32(SYMERRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	adapter->stats.mpc += er32(MPC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	adapter->stats.scc += er32(SCC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	adapter->stats.ecol += er32(ECOL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	adapter->stats.mcc += er32(MCC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	adapter->stats.latecol += er32(LATECOL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	adapter->stats.dc += er32(DC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	adapter->stats.sec += er32(SEC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	adapter->stats.rlec += er32(RLEC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	adapter->stats.xonrxc += er32(XONRXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	adapter->stats.xontxc += er32(XONTXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	adapter->stats.xoffrxc += er32(XOFFRXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	adapter->stats.xofftxc += er32(XOFFTXC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	adapter->stats.fcruc += er32(FCRUC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	adapter->stats.gptc += er32(GPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	adapter->stats.gotcl += er32(GOTCL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	adapter->stats.gotch += er32(GOTCH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	adapter->stats.rnbc += er32(RNBC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	adapter->stats.ruc += er32(RUC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	adapter->stats.rfc += er32(RFC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	adapter->stats.rjc += er32(RJC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	adapter->stats.torl += er32(TORL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	adapter->stats.torh += er32(TORH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	adapter->stats.totl += er32(TOTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	adapter->stats.toth += er32(TOTH);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	adapter->stats.tpr += er32(TPR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	adapter->stats.ptc64 += er32(PTC64);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	adapter->stats.ptc127 += er32(PTC127);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	adapter->stats.ptc255 += er32(PTC255);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
	adapter->stats.ptc511 += er32(PTC511);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
	adapter->stats.ptc1023 += er32(PTC1023);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	adapter->stats.ptc1522 += er32(PTC1522);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	adapter->stats.mptc += er32(MPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	adapter->stats.bptc += er32(BPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	/* used for adaptive IFS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
	hw->tx_packet_delta = er32(TPT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
	adapter->stats.tpt += hw->tx_packet_delta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	hw->collision_delta = er32(COLC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	adapter->stats.colc += hw->collision_delta;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	if (hw->mac_type >= e1000_82543) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		adapter->stats.algnerrc += er32(ALGNERRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		adapter->stats.rxerrc += er32(RXERRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		adapter->stats.tncrs += er32(TNCRS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		adapter->stats.cexterr += er32(CEXTERR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		adapter->stats.tsctc += er32(TSCTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		adapter->stats.tsctfc += er32(TSCTFC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
	/* Fill out the OS statistics structure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	netdev->stats.multicast = adapter->stats.mprc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	netdev->stats.collisions = adapter->stats.colc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	/* Rx Errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	/* RLEC on some newer hardware can be incorrect so build
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
	* our own version based on RUC and ROC */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
	netdev->stats.rx_errors = adapter->stats.rxerrc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		adapter->stats.crcerrs + adapter->stats.algnerrc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
		adapter->stats.ruc + adapter->stats.roc +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		adapter->stats.cexterr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	netdev->stats.rx_length_errors = adapter->stats.rlerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	/* Tx Errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	netdev->stats.tx_errors = adapter->stats.txerrc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	netdev->stats.tx_window_errors = adapter->stats.latecol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	if (hw->bad_tx_carr_stats_fd &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	    adapter->link_duplex == FULL_DUPLEX) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		netdev->stats.tx_carrier_errors = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		adapter->stats.tncrs = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	/* Tx Dropped needs to be maintained elsewhere */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	/* Phy Stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
	if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		if ((adapter->link_speed == SPEED_1000) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
			adapter->phy_stats.idle_errors += phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		if ((hw->mac_type <= e1000_82546) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		   (hw->phy_type == e1000_phy_m88) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
			adapter->phy_stats.receive_errors += phy_tmp;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	/* Management Stats */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	if (hw->has_smbus) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		adapter->stats.mgptc += er32(MGTPTC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
		adapter->stats.mgprc += er32(MGTPRC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		adapter->stats.mgpdc += er32(MGTPDC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
void ec_poll(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		e1000_watchdog(&adapter->watchdog_task.work);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
		adapter->ec_watchdog_jiffies = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	e1000_intr(0, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
 * e1000_intr - Interrupt Handler
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
 * @irq: interrupt number
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
 * @data: pointer to a network interface device structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
static irqreturn_t e1000_intr(int irq, void *data)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	struct net_device *netdev = data;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	u32 icr = er32(ICR);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	if (unlikely((!icr)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
		return IRQ_NONE;  /* Not our interrupt */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	 * we might have caused the interrupt, but the above
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	 * read cleared it, and just in case the driver is
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	 * down there is nothing to do so return handled
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		return IRQ_HANDLED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		hw->get_link_status = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		/* guard against interrupt when we're going down */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
			schedule_delayed_work(&adapter->watchdog_task, 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
		int i, ec_work_done = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		for (i = 0; i < E1000_MAX_INTR; i++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
							&ec_work_done, 100) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
 	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		/* disable interrupts, without the synchronize_irq bit */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		ew32(IMC, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		E1000_WRITE_FLUSH();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		if (likely(napi_schedule_prep(&adapter->napi))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
			adapter->total_tx_bytes = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
			adapter->total_tx_packets = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
			adapter->total_rx_bytes = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
			adapter->total_rx_packets = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
			__napi_schedule(&adapter->napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
			/* this really should not happen! if it does it is basically a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
			 * bug, but not a hard error, so enable ints and continue */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
			if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
				e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	return IRQ_HANDLED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
 * e1000_clean - NAPI Rx polling callback
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
 * EtherCAT: never called
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
static int e1000_clean(struct napi_struct *napi, int budget)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	int tx_clean_complete = 0, work_done = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	tx_clean_complete = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
	adapter->clean_rx(adapter, &adapter->rx_ring[0], &work_done, budget);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
	if (!tx_clean_complete)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
		work_done = budget;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	/* If budget not fully consumed, exit the polling mode */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	if (work_done < budget) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		if (likely(adapter->itr_setting & 3))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
			e1000_set_itr(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		napi_complete(napi);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
			e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	return work_done;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
			       struct e1000_tx_ring *tx_ring)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	struct e1000_tx_desc *tx_desc, *eop_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	unsigned int i, eop;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	unsigned int count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	unsigned int total_tx_bytes=0, total_tx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	unsigned int bytes_compl = 0, pkts_compl = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	i = tx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	eop = tx_ring->buffer_info[i].next_to_watch;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	       (count < tx_ring->count)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		rmb();	/* read buffer_info after eop_desc */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		for ( ; !cleaned; count++) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			tx_desc = E1000_TX_DESC(*tx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
			buffer_info = &tx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
			cleaned = (i == eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
			if (cleaned) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
				total_tx_packets += buffer_info->segs;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
				total_tx_bytes += buffer_info->bytecount;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
				if (buffer_info->skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
					bytes_compl += buffer_info->skb->len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
					pkts_compl++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
			tx_desc->upper.data = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
			if (unlikely(++i == tx_ring->count)) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		eop = tx_ring->buffer_info[i].next_to_watch;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	tx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
2599
4b0b906df1b4 Fixed bug concerning netdev_completed_queue(); thanks to B. Benner.
Florian Pose <fp@igh-essen.com>
parents: 2584
diff changeset
  4026
	if (!adapter->ecdev) {
4b0b906df1b4 Fixed bug concerning netdev_completed_queue(); thanks to B. Benner.
Florian Pose <fp@igh-essen.com>
parents: 2584
diff changeset
  4027
		netdev_completed_queue(netdev, pkts_compl, bytes_compl);
4b0b906df1b4 Fixed bug concerning netdev_completed_queue(); thanks to B. Benner.
Florian Pose <fp@igh-essen.com>
parents: 2584
diff changeset
  4028
	}
2584
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
#define TX_WAKE_THRESHOLD 32
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	if (!adapter->ecdev && unlikely(count && netif_carrier_ok(netdev) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		/* Make sure that anybody stopping the queue after this
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		 * sees the new next_to_clean.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
		smp_mb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		if (netif_queue_stopped(netdev) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		    !(test_bit(__E1000_DOWN, &adapter->flags))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
			netif_wake_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
			++adapter->restart_queue;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	if (!adapter->ecdev && adapter->detect_tx_hung) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
		/* Detect a transmit hang in hardware, this serializes the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
		 * check with the clearing of time_stamp and movement of i */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
		adapter->detect_tx_hung = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		if (tx_ring->buffer_info[eop].time_stamp &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
		               (adapter->tx_timeout_factor * HZ)) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
			/* detected Tx unit hang */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
			e_err(drv, "Detected Tx Unit Hang\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
			      "  Tx Queue             <%lu>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
			      "  TDH                  <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			      "  TDT                  <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			      "  next_to_use          <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			      "  next_to_clean        <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
			      "buffer_info[next_to_clean]\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
			      "  time_stamp           <%lx>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
			      "  next_to_watch        <%x>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
			      "  jiffies              <%lx>\n"
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			      "  next_to_watch.status <%x>\n",
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
				(unsigned long)((tx_ring - adapter->tx_ring) /
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
					sizeof(struct e1000_tx_ring)),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
				readl(hw->hw_addr + tx_ring->tdh),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
				readl(hw->hw_addr + tx_ring->tdt),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
				tx_ring->next_to_use,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
				tx_ring->next_to_clean,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
				tx_ring->buffer_info[eop].time_stamp,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
				eop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
				jiffies,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
				eop_desc->upper.fields.status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
			e1000_dump(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
			netif_stop_queue(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	adapter->total_tx_bytes += total_tx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	adapter->total_tx_packets += total_tx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
	netdev->stats.tx_bytes += total_tx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	netdev->stats.tx_packets += total_tx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	return count < tx_ring->count;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
 * e1000_rx_checksum - Receive Checksum Offload for 82543
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
 * @adapter:     board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
 * @status_err:  receive descriptor status and error fields
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
 * @csum:        receive descriptor csum field
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
 * @sk_buff:     socket buffer with received data
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
			      u32 csum, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	u16 status = (u16)status_err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	u8 errors = (u8)(status_err >> 24);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	skb_checksum_none_assert(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	/* 82543 or newer only */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	if (unlikely(hw->mac_type < e1000_82543)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	/* Ignore Checksum bit is set */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	/* TCP/UDP checksum error bit is set */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		/* let the stack verify checksum errors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
		adapter->hw_csum_err++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	/* TCP/UDP Checksum has not been calculated */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	if (!(status & E1000_RXD_STAT_TCPCS))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	/* It must be a TCP or UDP packet with a valid checksum */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
		/* TCP checksum is good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
		skb->ip_summed = CHECKSUM_UNNECESSARY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
	adapter->hw_csum_good++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
 * e1000_consume_page - helper function
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
                               u16 length)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	bi->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	skb->len += length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	skb->data_len += length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	skb->truesize += PAGE_SIZE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
 * e1000_receive_skb - helper function to handle rx indications
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
 * @status: descriptor status field as written by hardware
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
 * @skb: pointer to sk_buff to be indicated to stack
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
			      __le16 vlan, struct sk_buff *skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	skb->protocol = eth_type_trans(skb, adapter->netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	if (status & E1000_RXD_STAT_VP) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
		u16 vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
		__vlan_hwaccel_put_tag(skb, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
	napi_gro_receive(&adapter->napi, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
 * @rx_ring: ring to clean
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
 * @work_done: amount of napi work completed this call
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
 * @work_to_do: max amount of work allowed for this call to do
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
 * the return value indicates whether actual cleaning was done, there
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
 * is no guarantee that everything was cleaned
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
				     struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
				     int *work_done, int work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
	struct e1000_rx_desc *rx_desc, *next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
	struct e1000_buffer *buffer_info, *next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
	unsigned long irq_flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
	u32 length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	int cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
	unsigned int total_rx_bytes=0, total_rx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	i = rx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
		struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
		u8 status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
		if (*work_done >= work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		(*work_done)++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		rmb(); /* read descriptor and rx_buffer_info after status DD */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		status = rx_desc->status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		if (++i == rx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		prefetch(next_rxd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
		next_buffer = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		cleaned = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
		cleaned_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
		dma_unmap_page(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
			       buffer_info->length, DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
		length = le16_to_cpu(rx_desc->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		/* errors is only valid for DD + EOP descriptors */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
		if (!adapter->ecdev &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		    unlikely((status & E1000_RXD_STAT_EOP) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
			u8 *mapped;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
			u8 last_byte;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
			mapped = page_address(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
			last_byte = *(mapped + length - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
				       last_byte)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
				spin_lock_irqsave(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
				                  irq_flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
				e1000_tbi_adjust_stats(hw, &adapter->stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
						       length, mapped);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
				spin_unlock_irqrestore(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
				                       irq_flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
				length--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
				if (netdev->features & NETIF_F_RXALL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
					goto process_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
				/* recycle both page and skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
				/* an error means any chain goes out the window
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
				 * too */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
				if (rx_ring->rx_skb_top)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
					dev_kfree_skb(rx_ring->rx_skb_top);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
				rx_ring->rx_skb_top = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
				goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
#define rxtop rx_ring->rx_skb_top
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
process_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
		if (!(status & E1000_RXD_STAT_EOP)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
			/* this descriptor is only the beginning (or middle) */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
			if (!rxtop) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
				/* this is the beginning of a chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
				rxtop = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
				                   0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
				/* this is the middle of a chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
				skb_fill_page_desc(rxtop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
				    skb_shinfo(rxtop)->nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
				    buffer_info->page, 0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
				/* re-use the skb, only consumed the page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
			e1000_consume_page(buffer_info, rxtop, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			if (rxtop) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
				/* end of the chain */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
				skb_fill_page_desc(rxtop,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
				    skb_shinfo(rxtop)->nr_frags,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
				    buffer_info->page, 0, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
				/* re-use the current skb, we only consumed the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
				 * page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
				skb = rxtop;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
				rxtop = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
				e1000_consume_page(buffer_info, skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
				/* no chain, got EOP, this buf is the packet
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
				 * copybreak to save the put_page/alloc_page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
				if (length <= copybreak &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
				    skb_tailroom(skb) >= length) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
					u8 *vaddr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
					vaddr = kmap_atomic(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
					memcpy(skb_tail_pointer(skb), vaddr, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
					kunmap_atomic(vaddr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
					/* re-use the page, so don't erase
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
					 * buffer_info->page */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
					skb_put(skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
				} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
					skb_fill_page_desc(skb, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
					                   buffer_info->page, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
				                           length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
					e1000_consume_page(buffer_info, skb,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
					                   length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
		e1000_rx_checksum(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
		                  (u32)(status) |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
		                  ((u32)(rx_desc->errors) << 24),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		                  le16_to_cpu(rx_desc->csum), skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
		total_rx_bytes += (skb->len - 4); /* don't count FCS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
			pskb_trim(skb, skb->len - 4);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
		total_rx_packets++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		/* eth type trans needs skb->data to point to something */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
		if (!pskb_may_pull(skb, ETH_HLEN)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
			e_err(drv, "pskb_may_pull failed.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
			if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
				dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			ecdev_receive(adapter->ecdev, skb->data, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
			// No need to detect link status as
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
			// long as frames are received: Reset watchdog.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
			adapter->ec_watchdog_jiffies = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
next_desc:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		rx_desc->status = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
		/* return some buffers to hardware, one at a time is too slow */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		/* use prefetched values */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		rx_desc = next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		buffer_info = next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	rx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	if (cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	adapter->total_rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	adapter->total_rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	netdev->stats.rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	netdev->stats.rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	return cleaned;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
 * this should improve performance for small packets with large amounts
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
 * of reassembly being done in the stack
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
static void e1000_check_copybreak(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
				 struct e1000_buffer *buffer_info,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
				 u32 length, struct sk_buff **skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	struct sk_buff *new_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	if (adapter->ecdev || length > copybreak)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	new_skb = netdev_alloc_skb_ip_align(netdev, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	if (!new_skb)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	skb_copy_to_linear_data_offset(new_skb, -NET_IP_ALIGN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
				       (*skb)->data - NET_IP_ALIGN,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
				       length + NET_IP_ALIGN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	/* save the skb in buffer_info as good */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	buffer_info->skb = *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	*skb = new_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
 * @adapter: board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
 * @rx_ring: ring to clean
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
 * @work_done: amount of napi work completed this call
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
 * @work_to_do: max amount of work allowed for this call to do
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
			       struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			       int *work_done, int work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	struct e1000_rx_desc *rx_desc, *next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	struct e1000_buffer *buffer_info, *next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	unsigned long flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	u32 length;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	int cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	bool cleaned = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	unsigned int total_rx_bytes=0, total_rx_packets=0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	i = rx_ring->next_to_clean;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
		struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		u8 status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
		if (*work_done >= work_to_do)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		(*work_done)++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
		rmb(); /* read descriptor and rx_buffer_info after status DD */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		status = rx_desc->status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		prefetch(skb->data - NET_IP_ALIGN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		if (++i == rx_ring->count) i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		prefetch(next_rxd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		next_buffer = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		cleaned = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		cleaned_count++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
				 buffer_info->length, DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		length = le16_to_cpu(rx_desc->length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		/* !EOP means multiple descriptors were used to store a single
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		 * packet, if thats the case we need to toss it.  In fact, we
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
		 * to toss every packet with the EOP bit clear and the next
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		 * frame that _does_ have the EOP bit set, as it is by
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		 * definition only a frame fragment
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
			adapter->discarding = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		if (adapter->discarding) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
			/* All receives must fit into a single buffer */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
			e_dbg("Receive packet consumed multiple buffers\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
			/* recycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
			buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
			if (status & E1000_RXD_STAT_EOP)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
				adapter->discarding = false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
			goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		if (!adapter->ecdev &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		    unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
			u8 last_byte = *(skb->data + length - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
				       last_byte)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
				spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
				e1000_tbi_adjust_stats(hw, &adapter->stats,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
				                       length, skb->data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
				spin_unlock_irqrestore(&adapter->stats_lock,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
				                       flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
				length--;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
				if (netdev->features & NETIF_F_RXALL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
					goto process_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
				/* recycle */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
				buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
				goto next_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
process_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		total_rx_bytes += (length - 4); /* don't count FCS */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		total_rx_packets++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		if (likely(!(netdev->features & NETIF_F_RXFCS)))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
			/* adjust length to remove Ethernet CRC, this must be
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
			 * done after the TBI_ACCEPT workaround above
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
			 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
			length -= 4;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
		e1000_check_copybreak(netdev, buffer_info, length, &skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
		skb_put(skb, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		/* Receive Checksum Offload */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
		e1000_rx_checksum(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
				  (u32)(status) |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
				  ((u32)(rx_desc->errors) << 24),
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
				  le16_to_cpu(rx_desc->csum), skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			ecdev_receive(adapter->ecdev, skb->data, length);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
			// No need to detect link status as
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
			// long as frames are received: Reset watchdog.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
			adapter->ec_watchdog_jiffies = jiffies;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
			e1000_receive_skb(adapter, status, rx_desc->special, skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
next_desc:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		rx_desc->status = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		/* return some buffers to hardware, one at a time is too slow */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			cleaned_count = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
		/* use prefetched values */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		rx_desc = next_rxd;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		buffer_info = next_buffer;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	rx_ring->next_to_clean = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	if (cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	adapter->total_rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
	adapter->total_rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	netdev->stats.rx_bytes += total_rx_bytes;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	netdev->stats.rx_packets += total_rx_packets;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	return cleaned;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
 * @rx_ring: pointer to receive ring structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
 * @cleaned_count: number of buffers to allocate this pass
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
static void
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
                             struct e1000_rx_ring *rx_ring, int cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	struct e1000_rx_desc *rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	unsigned int bufsz = 256 - 16 /*for skb_reserve */ ;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	i = rx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	while (cleaned_count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		if (skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			skb_trim(skb, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			goto check_page;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		if (unlikely(!skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
			/* Better luck next round */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
		buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
		buffer_info->length = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
check_page:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		/* allocate a new page if necessary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		if (!buffer_info->page) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
			buffer_info->page = alloc_page(GFP_ATOMIC);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
			if (unlikely(!buffer_info->page)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		if (!buffer_info->dma) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
			buffer_info->dma = dma_map_page(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
			                                buffer_info->page, 0,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
							buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
							DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
				put_page(buffer_info->page);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
				dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
				buffer_info->page = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
				buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
				buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
				break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
		if (unlikely(++i == rx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
			i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	if (likely(rx_ring->next_to_use != i)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
		rx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
		if (unlikely(i-- == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
			i = (rx_ring->count - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
		/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
		 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
		 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
		wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
 * @adapter: address of board private structure
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
				   struct e1000_rx_ring *rx_ring,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
				   int cleaned_count)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
	struct net_device *netdev = adapter->netdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	struct pci_dev *pdev = adapter->pdev;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	struct e1000_rx_desc *rx_desc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	struct e1000_buffer *buffer_info;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	struct sk_buff *skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	unsigned int i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
	unsigned int bufsz = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	i = rx_ring->next_to_use;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	while (cleaned_count--) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		skb = buffer_info->skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
		if (skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
			skb_trim(skb, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
			goto map_skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
		if (unlikely(!skb)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
			/* Better luck next round */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
			break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
		/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
			struct sk_buff *oldskb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
			e_err(rx_err, "skb align check failed: %u bytes at "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
			      "%p\n", bufsz, skb->data);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
			/* Try again, without freeing the previous */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
			skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			/* Failed allocation, critical failure */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
			if (!skb) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
				dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
				/* give up */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
				dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
				dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
				adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
				break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
			/* Use new allocation */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
			dev_kfree_skb(oldskb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		buffer_info->skb = skb;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
		buffer_info->length = adapter->rx_buffer_len;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
map_skb:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		buffer_info->dma = dma_map_single(&pdev->dev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
						  skb->data,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
						  buffer_info->length,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
						  DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
			dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
			break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
		/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		 * XXX if it was allocated cleanly it will never map to a
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
		 * boundary crossing
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
		/* Fix for errata 23, can't cross 64kB boundary */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		if (!e1000_check_64k_bound(adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
					(void *)(unsigned long)buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
					adapter->rx_buffer_len)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
			e_err(rx_err, "dma align check failed: %u bytes at "
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
			      "%p\n", adapter->rx_buffer_len,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
			      (void *)(unsigned long)buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
			dev_kfree_skb(skb);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
			buffer_info->skb = NULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
			dma_unmap_single(&pdev->dev, buffer_info->dma,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
					 adapter->rx_buffer_len,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
					 DMA_FROM_DEVICE);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
			buffer_info->dma = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
			adapter->alloc_rx_buff_failed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
			break; /* while !buffer_info->skb */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		if (unlikely(++i == rx_ring->count))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
			i = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		buffer_info = &rx_ring->buffer_info[i];
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	if (likely(rx_ring->next_to_use != i)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
		rx_ring->next_to_use = i;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		if (unlikely(i-- == 0))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
			i = (rx_ring->count - 1);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
		/* Force memory writes to complete before letting h/w
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		 * know there are new descriptors to fetch.  (Only
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		 * applicable for weak-ordered memory model archs,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		 * such as IA-64). */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		wmb();
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		writel(i, hw->hw_addr + rx_ring->rdt);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
 * @adapter:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
static void e1000_smartspeed(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	u16 phy_status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	u16 phy_ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	if (adapter->smartspeed == 0) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		/* If Master/Slave config fault is asserted twice,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		 * we assume back-to-back */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
					    phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
			adapter->smartspeed++;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
			if (!e1000_phy_setup_autoneg(hw) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
			   !e1000_read_phy_reg(hw, PHY_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
				   	       &phy_ctrl)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
					     MII_CR_RESTART_AUTO_NEG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
				e1000_write_phy_reg(hw, PHY_CTRL,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
						    phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
		/* If still no link, perhaps using 2/3 pair cable */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
		phy_ctrl |= CR_1000T_MS_ENABLE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
		if (!e1000_phy_setup_autoneg(hw) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
				     MII_CR_RESTART_AUTO_NEG);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
		adapter->smartspeed = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
 * e1000_ioctl -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
 * @netdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
 * @ifreq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
 * @cmd:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
	switch (cmd) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
	case SIOCGMIIPHY:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	case SIOCGMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	case SIOCSMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
		return e1000_mii_ioctl(netdev, ifr, cmd);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 * e1000_mii_ioctl -
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
 * @netdev:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
 * @ifreq:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
 * @cmd:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
 **/
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
			   int cmd)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	struct mii_ioctl_data *data = if_mii(ifr);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	int retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	u16 mii_reg;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
	unsigned long flags;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
	if (hw->media_type != e1000_media_type_copper)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	switch (cmd) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	case SIOCGMIIPHY:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		data->phy_id = hw->phy_addr;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	case SIOCGMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
			return -EPERM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
		spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
				   &data->val_out)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
			return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	case SIOCSMIIREG:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
		if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
			return -EPERM;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
		if (data->reg_num & ~(0x1F))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
			return -EFAULT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		mii_reg = data->val_in;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		spin_lock_irqsave(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
		if (e1000_write_phy_reg(hw, data->reg_num,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
					mii_reg)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
			return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
		if (hw->media_type == e1000_media_type_copper) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
			switch (data->reg_num) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			case PHY_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
				if (mii_reg & MII_CR_POWER_DOWN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
					hw->autoneg = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
					hw->autoneg_advertised = 0x2F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
				} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
					u32 speed;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
					if (mii_reg & 0x40)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
						speed = SPEED_1000;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
					else if (mii_reg & 0x2000)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
						speed = SPEED_100;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
					else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
						speed = SPEED_10;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
					retval = e1000_set_spd_dplx(
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
						adapter, speed,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
						((mii_reg & 0x100)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
						 ? DUPLEX_FULL :
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
						 DUPLEX_HALF));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
					if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
						return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
				}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
				if (netif_running(adapter->netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
					e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
				else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
					e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
			case M88E1000_PHY_SPEC_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
			case M88E1000_EXT_PHY_SPEC_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
				if (e1000_phy_reset(hw))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
					return -EIO;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
		} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
			switch (data->reg_num) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
			case PHY_CTRL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
				if (mii_reg & MII_CR_POWER_DOWN)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
					break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
				if (netif_running(adapter->netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
					e1000_reinit_locked(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
				else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
					e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
				break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
			}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
		return -EOPNOTSUPP;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	return E1000_SUCCESS;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
void e1000_pci_set_mwi(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
	int ret_val = pci_set_mwi(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	if (ret_val)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
		e_err(probe, "Error in setting MWI\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
void e1000_pci_clear_mwi(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
	pci_clear_mwi(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
	return pcix_get_mmrbc(adapter->pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
	struct e1000_adapter *adapter = hw->back;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	pcix_set_mmrbc(adapter->pdev, mmrbc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	outl(value, port);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
static bool e1000_vlan_used(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	u16 vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
		return true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	return false;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
static void __e1000_vlan_mode(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
			      netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	u32 ctrl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	if (features & NETIF_F_HW_VLAN_RX) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
		/* enable VLAN tag insert/strip */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
		ctrl |= E1000_CTRL_VME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		/* disable VLAN tag insert/strip */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		ctrl &= ~E1000_CTRL_VME;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
	ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
				     bool filter_on)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	u32 rctl;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	__e1000_vlan_mode(adapter, adapter->netdev->features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	if (filter_on) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
		/* enable VLAN receive filtering */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		rctl &= ~E1000_RCTL_CFIEN;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
		if (!(adapter->netdev->flags & IFF_PROMISC))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
			rctl |= E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
		ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
		e1000_update_mng_vlan(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
		/* disable VLAN receive filtering */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
		rctl &= ~E1000_RCTL_VFE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		ew32(RCTL, rctl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
static void e1000_vlan_mode(struct net_device *netdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			    netdev_features_t features)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	__e1000_vlan_mode(adapter, features);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	u32 vfta, index;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	if ((hw->mng_cookie.status &
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	    (vid == adapter->mng_vlan_id))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
		return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		e1000_vlan_filter_on_off(adapter, true);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	/* add VID to filter table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	index = (vid >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
	vfta |= (1 << (vid & 0x1F));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
	e1000_write_vfta(hw, index, vfta);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	set_bit(vid, adapter->active_vlans);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	u32 vfta, index;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		e1000_irq_disable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
	if (!test_bit(__E1000_DOWN, &adapter->flags))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
		e1000_irq_enable(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
	/* remove VID from filter table */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
	index = (vid >> 5) & 0x7F;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
	vfta &= ~(1 << (vid & 0x1F));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
	e1000_write_vfta(hw, index, vfta);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	clear_bit(vid, adapter->active_vlans);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
		e1000_vlan_filter_on_off(adapter, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
static void e1000_restore_vlan(struct e1000_adapter *adapter)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	u16 vid;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	if (!e1000_vlan_used(adapter))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	e1000_vlan_filter_on_off(adapter, true);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
	hw->autoneg = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	/* Make sure dplx is at most 1 bit and lsb of speed is not set
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
	 * for the switch() below to work */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	if ((spd & 1) || (dplx & ~1))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	/* Fiber NICs only allow 1000 gbps Full duplex */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
	if ((hw->media_type == e1000_media_type_fiber) &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	    spd != SPEED_1000 &&
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	    dplx != DUPLEX_FULL)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	switch (spd + dplx) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	case SPEED_10 + DUPLEX_HALF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
		hw->forced_speed_duplex = e1000_10_half;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	case SPEED_10 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
		hw->forced_speed_duplex = e1000_10_full;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	case SPEED_100 + DUPLEX_HALF:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
		hw->forced_speed_duplex = e1000_100_half;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	case SPEED_100 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
		hw->forced_speed_duplex = e1000_100_full;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	case SPEED_1000 + DUPLEX_FULL:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
		hw->autoneg = 1;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
		break;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	default:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
		goto err_inval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	hw->mdix = AUTO_ALL_MODES;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
err_inval:
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	e_err(probe, "Unsupported Speed/Duplex configuration\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
	return -EINVAL;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
	u32 ctrl, ctrl_ext, rctl, status;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	u32 wufc = adapter->wol;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	int retval = 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
	netif_device_detach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
	retval = pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
	if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
		return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	status = er32(STATUS);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
	if (status & E1000_STATUS_LU)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
		wufc &= ~E1000_WUFC_LNKC;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
	if (wufc) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
		e1000_setup_rctl(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
		e1000_set_rx_mode(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
		rctl = er32(RCTL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
		/* turn on all-multi mode if wake on multicast is enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
		if (wufc & E1000_WUFC_MC)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
			rctl |= E1000_RCTL_MPE;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
		/* enable receives in the hardware */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		ew32(RCTL, rctl | E1000_RCTL_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
		if (hw->mac_type >= e1000_82540) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
			ctrl = er32(CTRL);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
			/* advertise wake from D3Cold */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
			#define E1000_CTRL_ADVD3WUC 0x00100000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
			/* phy power management enable */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
			ctrl |= E1000_CTRL_ADVD3WUC |
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
				E1000_CTRL_EN_PHY_PWR_MGMT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
			ew32(CTRL, ctrl);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		if (hw->media_type == e1000_media_type_fiber ||
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
		    hw->media_type == e1000_media_type_internal_serdes) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
			/* keep the laser running in D3 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
			ctrl_ext = er32(CTRL_EXT);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			ew32(CTRL_EXT, ctrl_ext);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		ew32(WUC, E1000_WUC_PME_EN);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
		ew32(WUFC, wufc);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
		ew32(WUC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
		ew32(WUFC, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	e1000_release_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	*enable_wake = !!wufc;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	/* make sure adapter isn't asleep if manageability is enabled */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	if (adapter->en_mng_pt)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
		*enable_wake = true;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
		e1000_free_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
#ifdef CONFIG_PM
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
	int retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	bool wake;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
	retval = __e1000_shutdown(pdev, &wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
	if (retval)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
		return retval;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	if (wake) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		pci_prepare_to_sleep(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
	} else {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
		pci_wake_from_d3(pdev, false);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
		pci_set_power_state(pdev, PCI_D3hot);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
static int e1000_resume(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	u32 err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	if (adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
		return -EBUSY;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
	pci_set_power_state(pdev, PCI_D0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
	pci_restore_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	pci_save_state(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
	if (adapter->need_ioport)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
		pr_err("Cannot enable PCI device from suspend\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
		return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	pci_enable_wake(pdev, PCI_D3hot, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	pci_enable_wake(pdev, PCI_D3cold, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
		err = e1000_request_irq(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
		if (err)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
			return err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	e1000_power_up_phy(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	ew32(WUS, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
		e1000_up(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	if (!adapter->ecdev) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
		netif_device_attach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
	return 0;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
static void e1000_shutdown(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	bool wake;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	__e1000_shutdown(pdev, &wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	if (system_state == SYSTEM_POWER_OFF) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
		pci_wake_from_d3(pdev, wake);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
		pci_set_power_state(pdev, PCI_D3hot);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
#ifdef CONFIG_NET_POLL_CONTROLLER
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
/*
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
 * Polling 'interrupt' - used by things like netconsole to send skbs
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
 * without having to re-enable interrupts. It's not called while
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
 * the interrupt routine is executing.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
static void e1000_netpoll(struct net_device *netdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
	disable_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	e1000_intr(adapter->pdev->irq, netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	enable_irq(adapter->pdev->irq);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
#endif
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
 * e1000_io_error_detected - called when PCI error is detected
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
 * @state: The current pci connection state
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
 * This function is called after a PCI bus error affecting
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
 * this device has been detected.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
						pci_channel_state_t state)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
	netif_device_detach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
	if (state == pci_channel_io_perm_failure)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
		return PCI_ERS_RESULT_DISCONNECT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
	if (netif_running(netdev))
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
		e1000_down(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	pci_disable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
	/* Request a slot slot reset. */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	return PCI_ERS_RESULT_NEED_RESET;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
 * e1000_io_slot_reset - called after the pci bus has been reset.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
 * Restart the card from scratch, as if from a cold-boot. Implementation
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
 * resembles the first-half of the e1000_resume routine.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
	struct e1000_hw *hw = &adapter->hw;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	int err;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	if (adapter->need_ioport)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
		err = pci_enable_device(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
	else
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
		err = pci_enable_device_mem(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
	if (err) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
		pr_err("Cannot re-enable PCI device after reset.\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		return PCI_ERS_RESULT_DISCONNECT;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
	pci_set_master(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
	pci_enable_wake(pdev, PCI_D3hot, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
	pci_enable_wake(pdev, PCI_D3cold, 0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	e1000_reset(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	ew32(WUS, ~0);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	return PCI_ERS_RESULT_RECOVERED;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
/**
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
 * e1000_io_resume - called when traffic can start flowing again.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
 * @pdev: Pointer to PCI device
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
 *
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
 * This callback is called when the error recovery driver tells us that
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
 * its OK to resume normal operation. Implementation resembles the
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
 * second-half of the e1000_resume routine.
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
 */
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
static void e1000_io_resume(struct pci_dev *pdev)
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
{
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
	struct net_device *netdev = pci_get_drvdata(pdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
	struct e1000_adapter *adapter = netdev_priv(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
	e1000_init_manageability(adapter);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
	if (netif_running(netdev)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
		if (e1000_up(adapter)) {
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
			pr_info("can't bring device back up after reset\n");
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
			return;
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
		}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
	}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
	netif_device_attach(netdev);
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
}
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
0e3d989ff233 Added all drivers for kernel 3.8.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
/* e1000_main.c */